2014-06-12 79 views
0

我很新的C++和我現在正在嘗試線程。 我想在while循環下的線程內創建一個線程。但我認爲這似乎沒有奏效。 目前我的代碼看起來是這樣的:在while循環中的另一個線程內的線程

#include <> 
std::vector<pthread_t> outer_thread, inner_thread; 

    void *inner_thread(void *ptr) 
    { 
     string data1; 
     data1 = *(reinterpret_cast<string*>(ptr)); 
     cout << "inner thread started " << data1; 

/* do something */ 
     cout << "inner thread stopped " << data1; 

pthread_exit(NULL); 
    return 0; 


    } 

    void *outer_thread(void *ptr) 
    { 
cout << "out thread started" << endl; 
//cout << ptr << endl; 
//cout << *(reinterpret_cast<string*>(ptr)) << endl; 
string data; 
data = *(reinterpret_cast<string*>(ptr)); 


     string str3; 
while (getline(data,str3)) 
{ 
     cout << "out thread started" << endl; 


pthread_t in_thread; 
in_vec.push_back(str3); 
       int create_thread2 = pthread_create(&in_thread, NULL, &inner_thread, reinterpret_cast<void*>(&(in_vec.at(j)))); 
       inner_thread.push_back(in_thread); 


     if (create_thread2 != 0) 
     cout << "Error : Thread"; 


     j++; 

     cout << "out thread ends " << j << create_thread2 << endl ; 

    } 
     for (int k = 0; k < j ; k++) 

{ 
pthread_join(inner_thread.at(k),NULL) ; 
} 

pthread_exit(NULL); 
    return 0; 

} 
    int main (int argc, char *argv[]) 
    { 
     int i = 0; 
     while (getline(gin,str)) 
     { 
string str1; 
       pthread_t out_thread; 
       cout << "str1" << str1 << endl; 
now_vec.push_back(str1); 
int create_thread = pthread_create(&out_thread, NULL, &outer_thread, reinterpret_cast<void*>(&(now_vec.at(i)))); 
       outer_thread.push_back(out_thread); 
       if (create_thread != 0) cout << "Error : Thread" ; 

     i++; 
     } 

for (int k = 0 ; k < i; k ++) 
{ 
cout << i << endl; 
//cout << "third thread " << outer_thread.at(1) << endl; 
cout << outer_thread.at(k) << endl; 
cout << "out out out" << endl; 
pthread_join(outer_thread.at(k),NULL) ; 
} 


    } 

我想讀一下包含的文件列表應該讀取的文件。我想同時讀取所有這些文件。 所有這些文件都包含信息並需要另一組線程來啓動另一個操作。所以這也需要同時完成。 這就是我有2套線程運行的原因。 讓我知道如果有更快,更簡單的方法來做到這一點?

它似乎等到內部線程完成,然後從下一次迭代開始。我想讓內部線程在外部線程內同時運行。我可以知道如何解決這個問題嗎?

+0

打開你的編譯器警告。你沒有返回值。 – chris

+3

你有[pthread_join](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html)*內循環...這就是爲什麼在等待。 – jsantander

+0

'pthread_t threads [i];'你在第一次迭代中沒有正確地分配('int i = 0;')。 –

回答

0

不知道你想要做什麼,但我希望來自simplying你的代碼中的許多語法錯誤當中,這是發生了什麼:

  1. 主線程產生一個線程(1),並等待(加入)
  2. (1)線程執行outer_thread併產生另一個線程(2)並等待它結束(加入)
  3. (2)線程執行inner_thread並結束。
  4. (2)加入並(1)線程能夠完成。
  5. (1)被加入並且主線程能夠進入下一次迭代。
  6. 過程再次開始。

請注意,您沒有任何並行執行,因爲您的線程正在等待其他完成。

請注意,在任務中拋出線程並不是加速的方式。

線程是的一種方式之一:

  • 使用的CPU資源(當你有多個CPU資源......,只使用盡可能多的線程,你有CPU資源)
  • 簡化組織更好通過將請求封裝爲線程(但這種技巧縮放非常糟糕)
+0

如何在這種情況下啓動並行執行? – user3309525

+0

@ user3309525不等待一個線程完成以開始下一個... – jsantander

+0

我不確定如何在while循環之前聲明線程,因爲我不確定將需要多少個線程。 – user3309525

2

您對線程操作的看法是錯誤的。一個線程不在另一個線程內運行。它們在同一個過程中是獨立的執行流,它們的共存是平坦的,而不是分層的。

一些簡單的規則,以多線程工作時遵循:

  • 創建線程是昂貴的,所以要避免創建和銷燬很快他們。最好在應用程序開始時創建一次線程,並在工作變得可用時將其分配。
  • 在做計算工作時,避免創建比在CPU上同時執行的更多的線程。任何額外的線程都會導致過度的上下文切換並減慢應用程序的速
  • 如果必須在線程之間共享數據結構,請儘量避免使用共享資源嘗試並找到無鎖實現。如果您的共享資源在無鎖實現中不可用,請使用鎖來保護它,但要非常小心,不正確地使用鎖可能會導致應用程序死鎖或應用程序的性能下降到串行執行情況(就像那裏只有一個線程)。

你的具體情況,如果你想通過並行處理他們加快多個文件的處理(假設這些線程需要實現的唯一任務是這些文件的處理),那麼一個可能的解決方案看起來像:

  1. 讀入文件的列表上
  2. 鴻溝操作列表段(爲你的CPU上的每個邏輯處理器一個部分)。
  3. 創建您的工作線程(每個邏輯處理器)傳遞它們的文件列表部分(不要嘗試在創建它的同一個循環中加入線程,這會阻塞,直到線程完成執行導致您的應用程序以並行方式執行,這是您提供的示例代碼中的情況)

工作線程可以遍歷文件列表,逐個讀取它們並處理它們。

與你提出的解決方案相反,這不會爲每個文件創建一個線程。相反,它會創建儘可能多的線程,可以在CPU上並行運行,避免過度的上下文切換。

上面的原始例如:

#include <pthread.h> 
#include <vector> 
#include <string> 

#define NUM_THREADS 4 

std::vector<std::string> work_pool[NUM_THREADS]; 

void *worker_thread(void *args); 

int main(int argc, char *argv[]) 
{ 
    pthread_t threads[NUM_THREADS]; 

    // Read list of files here, distribute them evenly amongst the work_pools 

    for (int i = 0; i < NUM_THREADS; i++) { 
     pthread_create(&threads[i], NULL, worker_thread, (void *)i); 
    } 

    for (int i = 0; i < NUM_THREADS; i++) { 
     pthread_join(threads[i], NULL); 
    } 

    return 0; 
} 

void *worker_thread(void *args) 
{ 
    const int id = (int)args; 
    std::vector<std::string>::iterator it; 

    for (it = work_pool[id].begin(); it != work_pool[id].end(); it++) { 
     // Read file and process it here 
    } 

    return NULL; 
} 
+0

我根據您的建議修改了腳本。不知道這是你的意思,但需要代碼的反饋 – user3309525

+0

我修改了腳本,但沒有正確地傳遞值在所有的地方。不知道什麼問題可能是! – user3309525

+0

問題在於,我永遠無法確定我需要的線程數量。 NUM_THREADS可以在0到10或20之間變化。 – user3309525