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;
}