2012-10-06 65 views
1

我是線程(和C/C++)的新手,我嘗試使用多線程來訪問共享變量。在共享變量的C++中使用pthread的多線程

在main中,我創建了一個變量char inputarray [100];

線程1:該線程將以2字節的突發讀取stdin中的數據,並將它們附加到輸入數組。 (通過輸入文件輸入)

線程2:此線程將一次讀取1個字節的數據,執行計算並將其數據放入輸出數組中。

線程3:該線程將以2個字節的突發從輸出數組輸出數據。 (標準輸出)

我試過輸入部分,並通過傳遞一個結構得到它的工作,但是想要做到這一點而不使用結構,但它一直給我的問題。

如果我可以得到輸入,我相信我可以使用類似的策略來完成輸出。任何幫助將不勝感激。

下面是輸入線程的粗略模板。

#include <stdio.h> 
#include <pthread.h> 

using namespace std; 

void* input(void* arg) { 
    char reading[3]; 
    fread(reading,1,2,stdin); 

    //append to char inputarray[]..??? 
} 

int main() { 
    char inputarray[100]; 
    pthread_t t1; 
    pthread_create(&t1, NULL, &input, &inputarray); 
    void *result; 
    pthread_join(t1,&result); 
    return 0; 
} 

回答

2

你是正確的軌道上:

作爲一個說明並行線程庫是C庫,所以你需要聲明回調的C函數:

extern "C" void* input(void* arg); 

個人而言,我會通過第一個元素的地址:

pthread_create(&t1, NULL, &input, &inputarray[0]); 

然後這會讓你的代碼看起來像這樣:

void* input(void* arg) { 

    try 
    { 
     char* inputarray = (char*)arg; 
     size_t inputLocation = 0; 

     // Need to make sure you don't over run the buffer etc... 
     while(!finished()) 
     { 
      fread(&inputarray[inputLocation],1,2,stdin); 
      inputLocation += 2; 
     } 
    } 
    catch(...){} // Must not let exceptions escape a thread. 
    return NULL; 
} 

這種風格的麻煩在於您將協調責任置於每個單獨的線程中。編寫器線程必須檢查讀取器線程是否必須檢查數據是否可用等等。所有這些都需要協調,所以現在您需要一些共享的互斥鎖和條件變量。

更好的選擇是將這個責任轉移到溝通的對象中。所以我會創建一個具有通信所需的基本操作的類,然後使其方法執行適當的檢查。

class Buffer 
{ 
    public: 
     void write(......); // 
     void read(.....); // 
    private: 
     // All the synchronization and make sure the two threads 
     // behave nicely inside the object. 
}; 

int main() 
{ 
     pthread_t threads[3]; 
     std::pair<Buffer, Buffer> comms; 
     // comms.first  inputToRead 
     // comms.second processesToOutput 


     pthread_create(&threads[0], NULL, &readInput, &comms.first); // Input 
     pthread_create(&threads[1], NULL, &procInput, &comms);   // Processing 
     pthread_create(&threads[2], NULL, &genOutput, &comms.second); // Output 

     void *result; 
     pthread_join(threads[0],&result); 
     pthread_join(threads[1],&result); 
     pthread_join(threads[2],&result); 

} 

補充說明:

除非有一些非常奇怪的有關數據處理。這可能會更快地寫成單線程應用程序。

+0

謝謝你的迴應,這是非常有幫助的。爲了解決您的問題,這是一種處理數據的非常奇怪的方式。我正在試圖爲線程難以置信的特定數據文件起草一個模板。作爲一個短期目標,我試圖優化一個小型程序,該程序需要2 kb數據塊中的2.5 MB數據。至於單線程應用程序,我目前有這樣的程序,並且出於純粹的好奇心,我想嘗試線程以查看速度是否完全不同。 –

8

幾個問題:

  1. 我認爲堆疊陣列的共享變量非常糟糕的選擇,因爲它有一個固定的大小,它不是從線程2清晰和3往哪裏放新元素或從哪裏讀取元素。我建議改用std::vectorstd::deque。 最初你的容器是空的。然後線程2將一些元素推送給它。 線3輪詢(或等待條件變量)的容器,一旦發現新的元素 - 它們打印

  2. 必須同步與互斥訪問共享變量(考慮並行線程互斥,std::mutexboost::mutex)。您可能還想使用條件變量來通知線程3有關隊列中的新元素。但是對於初始實施而言,這不是必需的。

  3. 你真的必須使用pthread原語嗎?通常情況下,使用std::thread,std::mutex(如果您有現代編譯器)或,boost::mutex則更容易和更安全(即異常安全)。