2012-04-21 163 views
1

我想讓我的概念更清楚一點,就C中的malloc()調用而言。我有一個多線程應用程序,其中主線程產生任意數量的工作線程(pthreads)。然後每個工作線程運行一個無限函數(包含的函數來自另一個.c文件,並實現一個while(1)),由它負責連續的網絡I/O。使用多線程分配內存時出現分段錯誤

對於每個線程,我需要一個哈希表,所以我使用了由glib提供的哈希映射。我做的是我在每個線程的函數內部初始化了一個哈希映射,後者爲該結構分配了一些初始內存,然後隨着需求的增加而增長。

現在,當我運行應用程序時,它拋出錯誤,包括分段錯誤和無法爲結構分配任何內存。我花了一段時間才發現錯誤是由於無法爲哈希映射分配內存。我認爲(仍然認爲)每個線程都有自己的內存空間,並且會爲其自己的內存塊中的相應哈希映射分配一塊內存。我能夠通過哈希地圖一樣(須藤代碼)的初始化之前和之後使用mutex鎖來修復錯誤:

lock mutex 
initialize hashmap 
unlock mutex 

初始化一個哈希表,被稱作每個線程的代碼是:

GHashTable *g_hash_table; 
    g_hash_table = g_hash_table_new (g_int_hash, g_int_equal); 

雖然它解決了這個問題,但我後來有點困惑。爲什麼在沒有使用鎖定的情況下會出現這個問題,因爲每個線程都有自己的內存空間用於其實現的功能,並且在分配自己的內存時不應與其他線程衝突。 所有的指導非常感謝。

謝謝。

回答

2

每個線程都沒有自己的內存空間 - 所有線程都可以訪問進程內所有線程的內存。

這就是說,每個線程都在這個空間內分配了自己的堆棧,所以auto-vars是沒問題的,而且malloc/free應該是線程安全的,所以動態分配的哈希映射線程堆棧上的自動指針)應該沒問題。

如果有選擇,請確保您鏈接的線程安全版本的庫。

互斥鎖不應該是必需的。如果它解決了這個問題,那麼你是對的 - 某些東西,malloc/free也許,在它應該是線程安全的時候是不安全的。

你肯定HashMap的代碼只引用自動或malloced存儲?沒有全局/靜態信息進入?

+0

是啊,一個線程自己的記憶我的意思是它自己的堆棧,這是一個線程中初始化任何結構應相應棧上分配的內存。 Glib是線程安全的,絕對是一件有趣的事情。我不確定這一點。希望有一些幫助來清除我的概念:) – Abdullah 2012-04-21 18:57:24

+0

添加散列映射的初始化代碼到問題。 – Abdullah 2012-04-21 19:02:28

+0

沒關係,但它調用了'g_hash_table_new'工廠函數,我們不知道那裏發生了什麼。 – 2012-04-21 19:11:46