#include <iostream>
#include <pthread.h>
using namespace std;
// 提示出租车到达的条件变量
pthread_cond_t taxiCond;
// 同步锁
pthread_mutex_t taxiMutex;
pthread_mutex_t aa;
int sum = 0;//记数变量,来确定有人要坐车
// 旅客到达等待出租车
void * traveler_arrive(void * name)
{
cout<< "Traveler: " <<(char *)name<< " needs a taxi now! " <<endl;
pthread_mutex_lock(&taxiMutex);
++sum;
pthread_cond_wait(&taxiCond, &taxiMutex);
pthread_mutex_unlock (&taxiMutex);
cout<< "Traveler: " << (char *)name << " now got a taxi! " <<endl;
pthread_exit( (void *)0 );
}
// 出租车到达
void * taxi_arrive(void *name)
{
cout<< "Taxi " <<(char *)name<< " arrives. " <<endl;
pthread_mutex_lock(&aa);//锁上发信号部分,防止后来的司机比先来的接走客人
while(1)//不停的循环直到有客户来
{
if(sum > 0)//来了客户,发出一个接走客户的信号,然后完成此线程
{
cout << (char*)name << " take you go!" << endl;
pthread_cond_signal(&taxiCond);
--sum;
pthread_mutex_unlock(&aa);
break;
}
}
pthread_exit( (void *)0 );
}
int main()
{ // 初始化
pthread_mutexattr_t attr;//用于定义互斥锁属性
taxiCond= PTHREAD_COND_INITIALIZER;
taxiMutex= PTHREAD_MUTEX_INITIALIZER;
aa = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&taxiMutex,&attr);//防止递归加锁后出现死锁
pthread_mutex_init(&aa,&attr);
pthread_t thread[10];
pthread_attr_t threadAttr;//初始化并加上线程属性
pthread_attr_init(&threadAttr);//这样设置以后,线程结束就会自动回收其占有的资源
pthread_attr_setdetachstate(&threadAttr,PTHREAD_CREATE_DETACHED);
pthread_create(&thread[6], &threadAttr, traveler_arrive, (void *)("teng"));
sleep(1);
pthread_create(&thread[7], &threadAttr, traveler_arrive, (void *)("hui"));
sleep(1);
pthread_create(&thread[0], &threadAttr, taxi_arrive, (void *)("0"));
sleep(1);
pthread_create(&thread[1], &threadAttr, traveler_arrive, (void *)("Susan"));
sleep(1);
pthread_create(&thread[4],&threadAttr,taxi_arrive,(void*)("4"));
sleep(1);
pthread_create(&thread[5],&threadAttr,taxi_arrive,(void*)("5"));
sleep(1);
pthread_create(&thread[3],&threadAttr,traveler_arrive,(void*)("liu"));
sleep(1);
pthread_create(&thread[2], &threadAttr, taxi_arrive, (void *)("2"));
sleep(1);
return 0;
}
|