2013-07-19 82 views
0

我寫帶班,並行線程,互斥體,和conds一個簡單的理髮店C/C++項目,但我遇到了一個問題,當我在一個循環中創建一個新的客戶對象:並行線程循環覆蓋指針

void BarberShop::simulate() { 
barber.start(); // start the barber 
int custId = 1; 
while(1) { 
    Customer c(custId, *this); 
    customers.push_back(c); 
    c.start(); 
    sleep(3); 
    custId++; 
} 

}

void Customer::start() { 
    pthread_create(&thread, NULL, &Customer::run, this); 
} 

void* Customer::run(void *ptr) { 
    Customer* data = reinterpret_cast<Customer*>(ptr); 
    while(1) { 
     printf("Customer %d running...\n", data->id); 
     sleep(3); 
    } 
} 

當我運行這個程序,它會創建線程不錯,但每當我提出一個新的線程,將會改寫ID在其他線程。輸出:

Customer 1 running... 1 sec 
Customer 1 running... 2 sec 
Customer 1 running... 3 sec 
Customer 2 running... 4 sec 
Customer 2 running... 4 sec 

在循環我說:

Customer c(...); 

難道不是創建一個新的實例每次循環迭代?後續線程爲什麼會覆蓋這個?

更新

class Customer 
{ 
private: 
    pthread_t thread; 
    pthread_cond_t cond; 
    pthread_mutex_t mutex; 
    static void* run(void *args); 
    int id; 
    BarberShop *bs; 
public: 
    Customer(int _id, BarberShop &_bs); 
    ~Customer(); 
    void start(); 
}; 

Customer::Customer(int _id, BarberShop &_bs) { 
id = _id; 
bs = &_bs; 
} 

更新2:隨着並行線程ID的

Customer 1 running...[3066383168] 
Customer 2 running...[3057990464] 
Customer 2 running...[3057990464] 
Customer 3 running...[3049597760] 
Customer 3 running...[3049597760] 
Customer 3 running...[3049597760] 
Customer 3 running...[3049597760] 
Customer 4 running...[3049597760] 
Customer 4 running...[3041205056] 
Customer 4 running...[3041205056] 
Customer 4 running...[3041205056] 
Customer 5 running...[3041205056] 
Customer 4 running...[3041205056] 
Customer 5 running...[3032812352] 
Customer 5 running...[3032812352] 
+0

你沒有在你的類中存儲客戶ID作爲一個靜態成員變量是你嗎?你能顯示你的構造函數的代碼嗎? – Jimbo

+0

@Jimbo已更新。 – user622469

+1

在同一個堆棧上,它始終是同一個客戶。 –

回答

1

在下面的部分

while(1) { 
    Customer c(custId, *this); 
    customers.push_back(c); 
    c.start(); 
    sleep(3); 
    custId++; 
} 

類實例c是本地的while循環的範圍。在循環的每次迭代結束時,c被銷燬。

所以,當你做customers.push_back(c) a 副本的類是採取(見(default) copy constructor)並添加到客戶名單。這意味着當你做c.start()時,你壓入你的矢量的副本有而不是已經啓動,只有環路本地的實例。在循環結束時,循環c的迭代被破壞。該循環再次開始並創建一個新的c

編輯: 見馬丁詹姆斯和凱西的言論,爲什麼你看到的行爲是發生

+0

其實......我錯了......這正是問題所在。而不是c.start()我需要:customers [customers.size() - 1] .start();謝謝! – user622469

+1

我想你錯過了凱西和馬丁詹姆斯的幾個要點。 – Jimbo

1

基於堆棧的汽車對象和多線程是犯錯..‘在任何情況下不融洽’ :)

您可以使用Customer *的矢量,如Casey所建議的。如果您要通過引用將對象傳遞給線程,請使用新動態分配它們。這樣可以避免同步對象的不可複製性問題等,並確保每個線程都獲得它自己的*對象。線程獲取所有權,如果在進程終止之前需要終止,則需要刪除傳遞的*對象。

或者,vector :: emplace Customer對象到vector中,以使auto/stack Customer消失。