Linux系统编程(九)线程同步
- 一、什么是线程同步?
- 二、互斥量
- 三、条件变量
- pthread_cond_wait函数
- pthread_cond_signal函数
- 生产者和消费者模型
一、什么是线程同步?
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。
二、互斥量
Linux中提供一把互斥锁mutex(也称之为互斥量)。每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁,资源还是共享的,线程间也还是竞争的,但通过“锁”就将资源的访问变成互斥操作,而后与时间有关的错误也不会再产生了。
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>pthread_mutex_t mutex; //定义锁
void* tfn(void* arg)
{srand(time(NULL));while (1) {//加锁pthread_mutex_lock(&mutex);printf("hello ");sleep(rand() % 3); /*模拟长时间操作共享资源,导致cpu易主,产生与时间有关的错误*/printf("world\n");//解锁pthread_mutex_lock(&mutex);pthread_mutex_unlock(&mutex);sleep(rand() % 3);}return NULL;
}int main(void)
{int flg = 5;pthread_t tid;srand(time(NULL));//初始化锁pthread_mutex_init(&mutex,NULL); //mutex==1pthread_create(&tid,NULL,tfn,NULL);while (1) {//加锁pthread_mutex_lock(&mutex);printf("HELLO ");sleep(rand() % 3);printf("WORLD\n");//解锁pthread_mutex_unlock(&mutex);sleep(rand() % 3);}pthread_cancel(tid);pthread_join(tid, NULL);pthread_mutex_destroy(&mutex);return 0;
}
三、条件变量
pthread_cond_wait函数
阻塞等待一个条件变量
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
函数作用:
- 阻塞等待条件变量cond(参1)满足
- 释放已掌握的互斥锁(解锁互斥量)相当于pthread_mutex_unlock(&mutex);
1.2.两步为一个原子操作。 - 当被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁pthread_mutex_lock(&mutex);
pthread_cond_signal函数
int pthread_cond_signal(pthread_cond_t *cond);
唤醒至少一个阻塞在条件变量上的线程
生产者和消费者模型
struct msg *head = NULL;
struct msg *mp = NULL;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;void *producter(void *arg)
{while (1) {mp = malloc(sizeof(struct msg));mp->num = rand() % 400 + 1;printf("---producted---%d\n", mp->num);pthread_mutex_lock(&mutex);mp->next = head;head = mp;pthread_mutex_unlock(&mutex);pthread_cond_signal(&has_product);sleep(rand() % 3);}return NULL;
}void *consumer(void *arg)
{while (1) {pthread_mutex_lock(&mutex);while (head == NULL) {pthread_cond_wait(&has_product, &mutex);}mp = head;head = mp->next;pthread_mutex_unlock(&mutex);printf("------------------consumer--%d\n", mp->num);free(mp);mp = NULL;sleep(rand() % 3);}return NULL;
}int main(void)
{pthread_t ptid, ctid;pthread_create(&ptid, NULL, producter, NULL);pthread_create(&ctid, NULL, consumer, NULL);pthread_join(ptid, NULL);pthread_join(ctid, NULL);return 0;
}