2010-02-28 33 views
1

我在Linux機器上使用C和pthread,並且在並行化程序時遇到了麻煩。線程打開文件的錯誤

我基本上試圖把一個數據文件夾分成幾組,每個組由一個線程處理,並在每個數據文件上運行一個函數。

我這樣做的方式是我有一個全局char **filename變量,其中filename [i] =數據文件的文件名。在主函數中,我將使用scandir讀入所有數據文件的文件名(減「。」和「..」),並將它們放入文件名變量中。然後創建4個(任意數量)線程,每個線程調用Process函數。在Process()中,每個線程僅打開(使用在Process()中聲明的FILE *fin),並使用start_index和end_index處理部分數據文件。例如,如果有100個文件,則每個線程將處理filename[0]filename[24]filename[25]filename[49]filename[50]filename[74]分別filename[75]filename[99]。完成後,所有4個線程的main()中都有一個pthread_join。

我已檢查文件名已正確存儲在main()和Process()中。不過,我不斷收到分段故障在這裏,在工藝():

for (i = start_index; i <= end_index ; i++) 
    fin = fopen(filename[i], "rb"); <--- Seg fault 

我真的不知道爲什麼因爲沒有線程試圖打開同一文件應該有一個錯誤。

請指教。

+2

請將代碼放在創建文件數組的地方...... – 2010-02-28 03:28:09

+0

您是否嘗試過在gdb中運行它並查看段錯誤時發生了什麼? – 2010-02-28 03:29:28

+1

而且,'filename [i]'是什麼時候它segfaults? – 2010-02-28 03:30:07

回答

0

我在這裏猜測,您可能將filename[i]設置爲namelist[i]->d_name,然後在namelist[i]上調用free(3)。之後,指向文件名的指針無效。或者free(3)發生在主線程和處理線程的比賽中。你真的需要每個字符串strdup(3),並且只有在你完成之後才釋放內存。

我當然可能是錯的,因爲給出的代碼沒有顯示字符串是如何分配的。

0

發生崩潰時,start_indexend_index以及i的值是多少?

如果i在控制之下,代碼不應該崩潰 - 所以這是我要檢查的第一件事。

顯示代碼片段可惡地泄漏文件流,因爲它在每次迭代時都會覆蓋fin。我認爲這是一種將測試代碼減少到最低限度而非(尚未)工作程序的實際行爲的假象。

+0

對於大多數Linux系統通常有1024個進程可以擁有的文件句柄數量有軟硬限制。確保你沒有多使用那個。 ulimit將顯示您允許單個進程擁有的文件數量。如果您打開更多,然後允許數量的文件更改限制,它應該工作。 – Rohit 2010-06-23 08:08:40

0

這與線程無關。

在分配文件名之前是否執行代碼的線程?你的索引是否正確?如果文件名來自scandir ...你是否複製了文件名或者只是指向scandir返回的值...因爲這個值長期不合適。您是否將文件名[i]指向調用scandir的函數堆棧中的字符串?

嘗試使用strdup來設置文件名[我],看看是否有效。