如果沒(méi)有對(duì)多線(xiàn)程做特殊處理的話(huà),任何會(huì)帶來(lái)副作用的函數(shù)內(nèi)都可能導(dǎo)致這個(gè)問(wèn)題。
給你舉個(gè)栗子:glibc的qsort函數(shù)在多線(xiàn)程使用的時(shí)候也可能會(huì)core。為什么呢?因?yàn)橛幸欢未a是這樣的
if (phys_pages == 0)
{
phys_pages = __sysconf (_SC_PHYS_PAGES);
//__sysconf函數(shù)在sysdeps/posix/sysconf.c中
//_SC_PHYS_PAGES對(duì)應(yīng)到函數(shù)__get_phys_pages()
//位于文件sysdeps/unix/sysv/linux/getsysstats.c中
//通過(guò)phys_pages_info()打開(kāi)/proc/meminfo來(lái)讀取內(nèi)存信息
//(這就定位到了qsort打開(kāi)文件的問(wèn)題)
if (phys_pages == -1)
/* Error while determining the memory size. So let's
assume there is enough memory. Otherwise the
implementer should provide a complete implementation of the `sysconf' function. */
phys_pages = (long int) (~0ul >> 1);
/* The following determines that we will never use more than
a quarter of the physical memory. */
phys_pages /= 4;
pagesize = __sysconf (_SC_PAGESIZE);
}
//注意,上面這一段if會(huì)產(chǎn)生競(jìng)爭(zhēng),出現(xiàn)線(xiàn)程安全安全:
//如果兩個(gè)線(xiàn)程都調(diào)用qsort,當(dāng)線(xiàn)程1獲取了phys_pages之后,線(xiàn)程2
//才到達(dá)if,線(xiàn)程2就會(huì)跳過(guò)這一段代碼,直接執(zhí)行下面的if語(yǔ)句——
//而此時(shí)pagesize尚未初始化(=0),于是就會(huì)出現(xiàn)除零錯(cuò)誤,導(dǎo)致
//core dump
/* Just a comment here. We cannot compute (phys_pages * pagesize) and compare the needed amount of memory against this value.
The problem is that some systems might have more physical
memory then can be represented with a `size_t' value (when
measured in bytes. */
/* If the memory requirements are too high don't allocate memory. */
//如果所需的內(nèi)存頁(yè)數(shù)大于總的可用內(nèi)存,則不分配內(nèi)存(防止swap降低性能)
if (size / pagesize > (size_t) phys_pages)
{
//直接使用stdlib/qsort.c中的 _quicksort 進(jìn)行排序
_quicksort (b, n, s, cmp, arg); return;
}