(本节笔记的实验代码,在这里)
1. 基本概念
多个线程按照规定的顺序来执行,即为线程同步。
2. 条件变量函数学习
2.1 初始化条件变量
函数名:
pthread_cond_init
函数原型: man pthread_cond_init
intpthread_cond_init(pthread_cond_t *restrict cond, const_pthread_condattr_t*restrict attr);
函数功能:
初始化一个已声明的条件变量。(动态初始化) /*pthread_cond_t cond= PTHREAD_COND_INITIALIZER(静态初始化) */
所属头文件:
<pthread.h>
返回值:
成功:返回0 失败 :返回错误编号
参数说明:
cond:需要初始化的条件变量的指针。
attr:条件变量属性,一般设NULL,Liunx自动设置属性。
2.2 等待条件变量成立
函数名:
pthread_cond_wait
函数原型: man pthread_cond_wait
intpthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrictmutex);
函数功能:
等待条件变量的条件成立。
所属头文件:
<pthread.h>
返回值:
成功:返回0 失败 :返回错误编号
参数说明:
cond:需要初始化的条件变量的指针。
mutex:在更新条件等待队列前加锁了的互斥锁地址,必须在判断前先加锁,再在判断后解锁。
2.3 设置条件变量成立
函数名:
pthread_cond_signal
函数原型: man pthread_cond_signal
intpthread_cond_signal(pthread_cond_t *cond);
函数功能:
向cond指定的条件变量发送一脱离组赛信号。(激活一个进入条件变量等待的线程)
所属头文件:
<pthread.h>
返回值:
成功:返回0 失败 :返回错误编号
参数说明:
cond :需要激活的条件变量的指针。
3. 综合实例
/* touch sync_1.c */
/* 在主进程中创建两线程studentA和studentB,使得studentA扫完五次地后,studentB再拖地(studentB采用轮询的方式检查studentA是否扫完) */
#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
pthread_tstu_thread[2];
pthread_mutex_tmutex_lock;
int number = 0;
void * studentA()
{
int i = 0;
for(i = 0; i <5; i++)
{
/* 扫一次地 */
pthread_mutex_lock(&mutex_lock);
number++
printf("StudentAhas finished the work one time!\n");
if(5 <=number)
{
printf("StudentAhas finished his works!!!!\n");
}
pthread_mutex_unlock(&mutex_lock);
/* 休息一秒钟 */
sleep(1);
}
/* 退出线程 */
pthread_exit(NULL);
}
void * studentB()
{
/* 循环判断A同学是否已经扫完5次地 */
while(1)
{
/* 如果已经扫完五次地,则拖地*/
pthread_mutex_lock(&mutex_lock);
if(5 <= number)
{
number =0;
printf("StudentBhas finished his work!!!\n");
pthread_mutex_unlock(&mutex_lock);
break;
}
else
{
pthread_mutex_unlock(&mutex_lock);
/* 休息2秒钟 */
sleep(2);
}
}
/* 退出线程 */
pthread_exit(NULL);
}
int main()
{
/* 初始化互斥锁 */
pthread_mutex_init(&mutex_lock);
/* 创建studentA线程 */
pthread_create(&stu_thread[0],NULL, studentA, NULL);
/* 创建studentB线程 */
pthread_create(&stu_thread[1],NULL, studentB, NULL);
/* 等待studentA线程结束 */
pthread_join(stu_thread[0],NULL);
/* 等待studentB线程结束 */
pthread_join(stu_thread[1],NULL;
return 0;
}
/* touch sync_2.c */
/* 在主进程中创建两线程studentA和studentB,使得studentA扫完五次地后,studentB再拖地(studentA扫完后通知studentB拖地) */
#include<stdio.h>
#include<pthread.h>
#include <unistd.h>
pthread_tstu_thread[2];
pthread_cond_tcond_ready = PTHREAD_COND_INITIALIZER;
pthread_mutex_tmutex_lock;
int number = 0;
void * studentA()
{
int i = 0;
for(i = 0; i <5; i++)
{
/* 扫一次地 */
pthread_mutex_lock(&mutex_lock);
number++
printf("StudentAhas finished the work one time!\n");
if(5 <=number)
{
printf("StudentAhas finished his works!!!!\n");
pthread_cond_signal(&cond_ready);
}
pthread_mutex_unlock(&mutex_lock);
/* 休息一秒钟 */
sleep(1);
}
/* 退出线程 */
pthread_exit(NULL);
}
void * studentB()
{
pthread_mutex_lock(&mutex_lock);
if(5 >= number)
{
/* 等待条件变量被激活 */
pthread_cond_wait(&cond_ready,&mutex_lock);
}
number = 0;
printf("StudentBhas finished his work!!!\n");
pthread_mutex_lock(&mutex_unlock);
/* 退出线程 */
pthread_exit(NULL);
}
int main()
{
/* 初始化互斥锁 */
pthread_mutex_init(&mutex_lock);
/* 创建studentA线程 */
pthread_create(&stu_thread[0],NULL, studentA, NULL);
/* 创建studentB线程 */
pthread_create(&stu_thread[1],NULL, studentB, NULL);
/* 等待studentA线程结束 */
pthread_join(stu_thread[0],NULL);
/* 等待studentB线程结束 */
pthread_join(stu_thread[1],NULL;
return 0;
}