1,使用旅客等出租車模型
2,使用線程編程:線程鎖,線程信號
3,設計要求:
1),沒有出租車,則旅客等待,且排隊。
2),有出租車,沒有旅客,則出租車排隊,先到出租車先搭載旅客
3),設計中使用旅客人數統計count,爲了解決如下邏輯
在 Linux 平臺,Jack 到了站臺一看沒人,觸發的條件變量被直接復位,於是 Jack 排在等待隊列裏面。來遲一秒的 Susan 小姐到了站臺卻看不到在那裏等待的 Jack,只能等待,直到 Mike 開車趕到,重新觸發條件變量,Susan 才上了 Mike 的車。這對於在排隊系統前面的 Jack 是不公平的,而問題癥結是在於 Linux 平臺上條件變量觸發的自動復位引起的一個 Bug 。
條件變量在 Linux 平臺上的這種模型很難說好壞。但是在實際開發中,我們可以對代碼稍加改進就可以避免這種差異的發生。由於這種差異只發生在觸發沒有被線程等待在條件變量的時刻,因此我們只需要掌握好觸發的時機即可。最簡單的做法是增加一個計數器記錄等待線程的個數,在決定觸發條件變量前檢查下該變量即可。
代碼清單:
#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;
int count = 0;
pthread_mutex_t lock;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *travelerArrave(void *name)
{
cout<<"Name: "<<(char *)name<<" Need car"<<endl;
pthread_mutex_lock(&lock);
count++;
pthread_cond_wait(&cond,&lock);
pthread_mutex_unlock(&lock);
cout<<(char *)name<<" is leaved"<<endl;
pthread_exit(NULL);
}
void *taxiArrave(void *name)
{
cout << "Driver: "<<(char *)name << " arrives."<< endl;
while(1){
pthread_mutex_lock(&lock);
if(count > 0){/*防止旅客後到,先到司機被重置問題*/
pthread_cond_signal(&cond);
count--;
pthread_mutex_unlock(&lock);
break;
}
pthread_mutex_unlock(&lock);
}
cout <<"Driver: "<<(char *)name << " got traveler"<<endl;
pthread_exit(NULL);
}
int main(void)
{
pthread_t thread;
pthread_attr_t Attr;
pthread_attr_init(&Attr);
pthread_mutex_init(&lock,NULL);
pthread_create(&thread,&Attr,travelerArrave,(void *)"Susan");
sleep(3);
pthread_create(&thread,&Attr,taxiArrave,(void *)"Jack");
sleep(3);
pthread_create(&thread,&Attr,taxiArrave,(void *)"Mark");
sleep(3);
return 0;
}
關於Linux下的線程退出:
1)phtread_exit((void *)0);
此函數用於線程函數中,(void *)0 即此函數的返回值。
2) int pthread_join(pthread_t th, void **thread_return); 獲取線程函數的返回值,注意此函數是阻塞等待線程函數退出。