创建三个线程,线程名分别为:A、B、C,各线程循环输出它们各自的线程名,但是最终打印出来的应当是ABC循环,不可乱序,循环10次后退出。
我们需要三个全局变量
//定义变量条件
pthread_cond_t cond;
//互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int flag = 0;
先创建条件变量
//创建一个条件变量
if(pthread_cond_init(&cond, NULL) != 0)
{
perror("pthread_cond_init");
return -1;
}
printf("创建条件变量成功\n");
创建三个线程
pthread_t A, B, C;
if(pthread_create(&A, NULL, callBack1, NULL) != 0)
{
perror("pthread_create");
return -1;
}
if(pthread_create(&B, NULL, callBack2, NULL) != 0)
{
perror("pthread_create");
return -1;
}
if(pthread_create(&C, NULL, callBack3, NULL) != 0)
{
perror("pthread_create");
return -1;
}
接下来是线程内的内容,每个线程的内部大同小异。我先利用flag对线程顺序进行编号,A:0,B:1,C:2 。当它们遇到对应flag才被激活,采用条件变量,是为了防止cpu空跑线程时间片浪费资源。
以A线程为例
void *callBack1(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex); //上互斥锁
while(flag != 0)
{
//当前线程休眠,同时设置唤醒条件
//解开互斥锁,等待被唤醒
pthread_cond_wait(&cond, &mutex);
//被唤醒后,尝试上锁
//如果上锁失败,则继续回到cond上休眠
//如果成功,则会从当前位置继续往后执行
//然后循环判断flag是否为0,为0则出去打印A
}
printf("A");
flag = 1; //把flag换成执行B线程需要的值
//唤醒睡在指定条件变量上的线程
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
C线程略有不同,主要是打印完C后要额外换个行,比较美观(雾)。因为要循环10次退出,要在C线程内定义一个变量counst判断输出次数,到10次后直接用exit退出整个程序。如果你采用break,或者return,则会导致别的线程没有退出而卡死。
如果执意不用exit(0)也可以在主函数的末尾,回收线程A、B的函数前,申请强制结束线程A、B(用 pthread_cancel函数)用法:pthread_cancel(线程id)。