2012-03-11 83 views
0

我正在開發一個項目,我需要讓程序在多個線程上運行。但是,我遇到了一些問題。多線程(pthreads)

在我的程序中,我有一個稱爲'func_call'的附件功能。 如果我用這個在我的代碼:

func_call((void*) &my_pixels); 

程序運行正常。

但是,如果我嘗試創建一個線程,然後運行該函數,程序將運行到一個分段錯誤。

pthread_t thread; 
pthread_create (&thread, NULL, (void*)&func_call, (void*) &my_pixels); 

我在我的程序中包含了pthread.h。任何想法可能是錯誤的?

+0

有點難以從這裏給出的小碎片中分辨出來,但是my_pixels參數超出了範圍,然後它所佔用的內存正在被一些其他值導致隨機指針值覆蓋 – Nick 2012-03-11 01:06:31

+0

my_pixels是結構體的一個實例與我需要發送該函數的變量。在調用pthread之前,我在main函數中初始化了struct和它的變量。一旦程序進入func_call函數,它將在本地保存變量。 – user1261711 2012-03-11 01:09:11

+0

@user:my_pixels的壽命是多少? 'func_call'如何使用線程參數?主線程和'func_call'之間是否有同步?請顯示代碼;一個解釋不會提供所有相關的細節。 – 2012-03-11 01:18:00

回答

0

你是不是在一個線程安全的方式來處理數據:

  • 從線程的說法,這是一個指向主線程的my_pixels變量的線程副本的數據;主線程可能會退出,使得my_pixles無效。
  • 線程使用scene,主線程調用free_scene()就可以了,這是我想象使它無效
  • 線程調用printf(),主線程關閉stdout(一種不尋常的本身)
  • 線程更新picture陣列,主線程訪問picture輸出數據從它

它看起來像你應該只是等待線程創建後完成其工作 - 呼叫pthread_join()做到這一點。

對於單線程來說,這似乎毫無意義(你只是將一個多線程程序變成了一個單線程程序)。但是,在註釋掉的代碼的基礎上,它看起來像你打算啓動幾個在數據塊上工作的線程。因此,當您再次嘗試時,請確保您加入所有您開始的線程。只要線程不修改相同的數據,它就可以工作。請注意,您需要爲每個線程使用單獨的my_pixels實例(創建它們的一個陣列,就像您使用pthreads一樣),或者某些線程可能會獲取用於不同線程的參數。

+0

這樣做!謝謝一堆!所以要加入線程,一個簡單的for循環就足夠了,是嗎? – user1261711 2012-03-11 02:37:16

+0

@user:一個簡單的循環應該做的伎倆。 – 2012-03-11 02:45:03

0

不知道func_call做什麼,很難給你一個答案。儘管如此,這裏有幾個可能性

  1. func_call是否使用某種全局狀態 - 檢查是否從線程內正確初始化。線程的執行順序並不總是每次執行相同
  2. 不知道你的操作系統(AIX/Linux/Solaris上等),它是很難回答這個問題,但請檢查您的編譯選項
  3. 請提供signal對於所有的線程來說,至少要有幾行堆棧跟蹤。您可以自行檢查的一件事是打印線程的堆棧軌跡(使用基於調試器的threads/threadpthreadthread current <x>)以及是否存在正在訪問的公用數據。當兩個線程試圖讀取另一個(未提交的)更改時,很可能發生段錯誤

希望有所幫助。我想問題是全局的picture數組。你似乎在沒有任何警衛的情況下在線程函數中修改它。您使用pxpy循環,並且所有線程將具有相同的pxpy,並將嘗試同時寫入picture陣列。請嘗試修改您的代碼,以防止多個線程踩在彼此的數據修改。

+0

感謝您的回覆。我很確定func_call被正確初始化。它作爲獨立功能運行得非常好。我用C編寫這個代碼,但是在Linux終端上運行它。此外,我目前正在試圖讓這個代碼只在一個線程上工作,然後再轉到多線程。所以,我認爲segfault必須從別的東西出來。 – user1261711 2012-03-11 01:15:29

+0

核心文件的堆棧跟蹤是否有助於縮小問題原因的可能性。就像@尼克提到的那樣,你的數據中的一些指針可能會損壞導致段錯誤 – Gangadhar 2012-03-11 01:19:16

+0

回溯不起作用。我相信這是我指責的一個問題,所以我試圖用幾個不同的斷點進行調試。 – user1261711 2012-03-11 01:47:08

0

func_call函數,還是函數指針?如果它是一個函數指針,那麼存在你的問題:你得到了一個函數指針的地址,然後將其轉換。

人們猜測,因爲你只提供了一小部分程序,其中提到的名字如func_call,沒有聲明的範圍。

由於您將(void *)表達式傳遞給函數指針參數,因此編譯器必須向您提供有關此程序的診斷信息。

以與pthread_create兼容的方式定義線程函數,然後在沒有任何強制轉換的情況下調用它。