2014-02-19 88 views
0

我瞭解多線程程序和我期待下面的代碼片斷是打印的無限循環「foo",而不是什麼都不會發生在pthread_create不正確執行

期望:

foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo

實況:

就好像甚至沒有被創建的線程,我在做什麼錯???如何創建一個線程將執行任何功能被分配給它

源代碼

#include <pthread.h> 
#include <stdlib.h> 

#include <stdio.h> 

#include <string.h> 
#include <iostream> 

void* print(void*); 

struct threadInfo 
{ 

    int threadID; 
    int threadNo; 

}; 

int main() 
{ 
    pthread_t thread[3]; 
    bool cont = false; 
    int i = 1; 
    int max = 3; 

    while (cont == false) 
    { 
     if (i <= max) 
     { 
      threadInfo t_info; 
      t_info.threadID = i ; 
      t_info.threadNo = i ; 
      pthread_create(&thread[i-1],NULL,print,(void*)&t_info); 

      i++; 
     } 
    } 





} 

void* print(void* arg) 
{ 
    std::cout << "Foo" ; 
    pthread_exit(NULL); 
} 

下面這段代碼是在Ubuntu的命令行編譯使用以下命令

g++ test.cpp -o test -lpthread 
+0

檢查phread_create的返回值,不檢查它的壞習慣 – Tebe

+0

我猜你的線程不會刷新它們的輸出......但即便如此,你只會得到FooFooFoo,即每個線程有一個Foo – djf

回答

2

線程已創建,但在它們可以運行之前,主線程退出,程序終止(它也是UB)。你必須等待你的主題:pthread_join

是不需要的while (cont == false)

+0

真的是主線程退出?它不是在一個無限循環中嗎? –

+0

@erenon其無限循環,我看不到主線程如何在子線程之前退出 – Computernerd

0

主線程可能結束(和tremrinates所有其他線程本)任何其他線程打印出任何東西之前。

要解決此問題,請在結束前在所有其他線程上使主線程連接到(所有創建的線程ID爲pthread_join()),或者使用pthread_exit()結束主線程。


又路過struct threadInfo各胎面的相同實例(即:(void*)&t_info)地址很可能不是你想要的。

1

沒有什麼,因爲打印輸出緩衝器不刷新

print功能,例如做

std::cout << "Foo" << std::flush; 
+0

爲什麼我需要刷新輸出緩衝區?爲什麼foo的輸出在3次後停止,應該是無限的? – Computernerd

+0

@Computernerd因爲它不是自動完成的。如果緩衝區沒有被刷新,實際上沒有任何打印,它只是存儲在內存緩衝區中。 –

+0

怎麼進來一個正常的程序,我可以只是cout和它自動刷新 – Computernerd

0

pthreads沒有問題。如果你想確保在輸出序列,你需要附上打印出帶有鎖和沖洗管,這樣就強制執行,

1. A thread only finishes once the message has actually been printed out 
2. Threads wait for each other so that no two threads write to the output at the same time 
1

我哦,我......從哪裏開始?

Joachim Pileborg給出了你看不到東西的原因:線程創建完成並完成他們的工作,但由於你的主程序永遠不會退出,也沒有人輸出換行符,緩衝輸出永遠不會被刷新。

您的主程序正在浪費CPU永遠不會改變的標誌上的循環。嘗試使線程與標誌同步是非常糟糕的,儘管愚蠢的新的C++ 11擴展使得原子變量成爲線程編程的alpha和omega。
您必須使用某種同步器來等待線程終止。最常見的機制是pthread_join

將相同的參數實例傳遞給線程的每個實例會創建完美的競爭條件。您無法保證線程將按您的預定順序讀取參數(即在主循環更改它們以準備下一次線程啓動之前)。您應該將每個線程傳遞給自己的私人實例t_info(或者在此結構上設置某種同步機制)。

即使在修復所有這些問題後,由於每個線程在一次打印後退出,因此應該只需要3個「Foo」。

而且由於你沒有序列化cout訪問(即,你不用像互斥體那樣的某種同步對象來保護它們),所以你的各個線程的輸出可能會隨機混合(即你可以看到類似「FoFFooooo」的東西)。

+0

爲什麼不在每個線程退出後創建新線程? – Computernerd

+0

您的'if(i <= max)'測試阻止創建超過3個線程。 –

+0

我做了ia全局變量,並在打印函數中添加了i--新程序打印foo 200次,但它仍然不是無限的 – Computernerd