多執行緒程式設計之六:pthread訊號量
阿新 • • 發佈:2019-02-11
###Date: 2017/11/13
轉載自:http://blog.csdn.net/lovecodeless/article/details/24919511 Pthread是 POSIX threads 的簡稱,是POSIX的執行緒標準。 互斥量用來處理一個共享資源的同步訪問問題,當有多個共享資源時,就需要用到訊號量機制。 訊號量機制用於保證兩個或多個共享資源被執行緒協調地同步使用,訊號量的值對應當前可用資源的數量。 1.訊號量(samaphore): 訊號量機制通過訊號量的值控制可用資源的數量。執行緒訪問共享資源前,需要申請獲取一個訊號量,如果訊號量為0,說明當前無可用的資源,執行緒無法獲取訊號量,則該執行緒會等待其他資源釋放訊號量(訊號量加1)。如果訊號量不為0,說明當前有可用的資源,此時執行緒佔用一個資源,對應訊號量減1。初始化訊號量:
int sem_init(sem_t *sem, int pshared, unsigned int val); 該函式第一個引數為訊號量指標,第二個引數為訊號量型別(一般設定為0),第三個為訊號量初始值。第二個引數pshared為0時,該程序內所有執行緒可用,不為0時不同程序間可用。
訊號量減1:
int sem_wait(sem_t *sem); 該函式申請一個訊號量,當前無可用訊號量則等待,有可用訊號量時佔用一個訊號量,對訊號量的值減1。
訊號量加1:
int sem_post(sem_t *sem); 該函式釋放一個訊號量,訊號量的值加1。
銷燬訊號量:
int sem_destory(sem_t *sem); 該函式銷燬訊號量。 3.牛刀小試: 採用訊號量機制,解決蘋果橙子問題:一個能放N(這裡N設為3)個水果的盤子,爸爸只往盤子裡放蘋果,媽媽只放橙子,女兒只吃盤子裡的橙子,兒子只吃蘋果。
#include <stdio.h>
#include <pthread.h>
#include <Windows.h>
#include <semaphore.h>
#pragma comment(lib, "pthreadVC2.lib") //必須加上這句
sem_t empty; //控制盤子裡可放的水果數
sem_t apple; //控制蘋果數
sem_t orange; //控制橙子數
pthread_mutex_t work_mutex; //宣告互斥量work_mutex
void *procf(void *arg) //father執行緒
{
while (1){
sem_wait(&empty); //佔用一個盤子空間,可放水果數減1
pthread_mutex_lock(&work_mutex); //加鎖
printf("爸爸放入一個蘋果!\n");
sem_post(&apple); //釋放一個apple訊號了,可吃蘋果數加1
pthread_mutex_unlock(&work_mutex); //解鎖
Sleep(3000);
}
}
void *procm(void *arg) //mother執行緒
{
while (1){
sem_wait(&empty);
pthread_mutex_lock(&work_mutex); //加鎖
printf("媽媽放入一個橙子!\n");
sem_post(&orange);
pthread_mutex_unlock(&work_mutex); //解鎖
Sleep(4000);
}
}
void *procs(void *arg) //son執行緒
{
while (1){
sem_wait(&apple); //佔用一個蘋果訊號量,可吃蘋果數減1
pthread_mutex_lock(&work_mutex); //加鎖
printf("兒子吃了一個蘋果!\n");
sem_post(&empty); //吃了一個蘋果,釋放一個盤子空間,可放水果數加1
pthread_mutex_unlock(&work_mutex); //解鎖
Sleep(1000);
}
}
void *procd(void *arg) //daughter執行緒
{
while (1){
sem_wait(&orange);
pthread_mutex_lock(&work_mutex); //加鎖
printf("女兒吃了一個橙子!\n");
sem_post(&empty);
pthread_mutex_unlock(&work_mutex); //解鎖
Sleep(2000);
}
}
void main()
{
pthread_t father; //定義執行緒
pthread_t mother;
pthread_t son;
pthread_t daughter;
sem_init(&empty, 0, 3); //訊號量初始化
sem_init(&apple, 0, 0);
sem_init(&orange, 0, 0);
pthread_mutex_init(&work_mutex, NULL); //初始化互斥量
pthread_create(&father, NULL, procf, NULL); //建立執行緒
pthread_create(&mother, NULL, procm, NULL);
pthread_create(&daughter, NULL, procd, NULL);
pthread_create(&son, NULL, procs, NULL);
Sleep(1000000000);
}
result: