线程加锁与同步,pthread_mutex_lock,pthread_mutex_unlock,pthread_cond_wait,pthread_cond_signal
线程之间的同步是通过临界资源来实现的,简言之,临界资源就是全局变量,而同步就是一个线程使另一个线程的条件成立,唤醒阻塞的线程,然后将CPU控制权给它,此时为了防止线程混乱,最好将自己的条件变为假,等待另一个线程使自己的条件为真。
注意事项:
- 一个线程调用pthread_cond_wait()阻塞等待时,后面的代码不会再执行。而当另一个线程调用唤醒该线程后,该线程继续从阻塞的地方向下执行。
- 一个线程调用pthread_cond_signal()唤醒另外的线程,自己后边的代码继续执行。
- 在线程调用pthread_cond_wait()阻塞的时候,该线程必须处于加锁状态,即调用pthread_mutex_lock()。
- 在线程调用pthread_cond_signal()唤醒其他线程,把CPU控制权给出来的时候,自身一定要调用pthread_mutex_unlock()进行解锁。
其他不多分享,运行代码如下:
#include<pthread.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//init cond
void *thread1(void*);
void *thread2(void*);
int i = 1; //global
int main(void){
pthread_t t_a;
pthread_t t_b;//two thread
pthread_create(&t_a,NULL,thread2,(void*)NULL);
pthread_create(&t_b,NULL,thread1,(void*)NULL);//Create thread
// printf("t_a:0x%x, t_b:0x%x:\n", t_a, t_b);
pthread_join(t_b,NULL);//wait a_b thread end
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
exit(0);
}
void *thread1(void *junk)
{
printf("call thread1 \n");
while(i<9)
{
if(i%2 == 0)
{
pthread_mutex_lock(&mutex); //互斥锁
printf("**************** call thread1 ****************\n");
printf("*** thread1: %d\n",i);
printf("**************** thread1 end ****************\n");
i++;
pthread_cond_signal(&cond); // 发信号唤醒其他线程,剩余代码继续执行,当沉睡的时候唤醒其他线程。其他线程执行完继续执行剩余代码
printf("thread1 give up to 2\n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
}
void *thread2(void*junk)
{
printf("call thread2 \n");
while(i < 9)
{
if(i%2 != 0)
{
pthread_mutex_lock(&mutex);
printf("**************** call thread2 ****************\n");
printf("*** thread2: %d\n",i);
printf("**************** thread2 end ****************\n");
i++;
pthread_cond_wait(&cond,&mutex); //wait 马上把权限给出去,不执行剩余代码
printf("thread2 have been weak up!\n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
}