【C/C++多线程编程之七】pthread信号量
多線程編程之信號量
? ? ?Pthread是 POSIX threads 的簡稱,是POSIX的線程標準。
? ? ? ? ?互斥量用來處理一個共享資源的同步訪問問題,當有多個共享資源時,就需要用到信號量機制。
? ? ? ? ?信號量機制用于保證兩個或多個共享資源被線程協調地同步使用,信號量的值對應當前可用資源的數量。
? ? ? ? ?1.信號量(samaphore):
? ? ? ? 信號量機制通過信號量的值控制可用資源的數量。線程訪問共享資源前,需要申請獲取一個信號量,如果信號量為0,說明當前無可用的資源,線程無法獲取信號量,則該線程會等待其他資源釋放信號量(信號量加1)。如果信號量不為0,說明當前有可用的資源,此時線程占用一個資源,對應信號量減1。
? ? ? ? 舉例:
? ? ? ? 停車場有5個停車位,汽車可使用停車位。在這里5個停車位是共享的資源,汽車是線程。開始信號量為5,表明此時有5個停車位可用。一輛汽車進入停車場前,先查詢信號量的值,不為0表明有可用停車位,汽車進入停車場并使用一個停車位,信號量減1,表明占用一個停車位,可用數減少。
? ? ? ?
? ? ? ? ? ?2.信號量基本函數:
? ? ? ? ?#include <semaphore.h>
初始化信號量:
? ? ? ? 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)個水果的盤子,爸爸只往盤子里放蘋果,媽媽只放橙子,女兒只吃盤子里的橙子,兒子只吃蘋果。
? ? ? ? 采用三個信號量:
? ? ? ? 1.sem_t empty:信號量empty控制盤子可放水果數,初始為3,因為開始盤子為空可放水果數為3。
? ? ? ? 2.sem_t ?apple ;信號量apple控制兒子可吃的蘋果數,初始為0,因為開始盤子里沒蘋果。
? ? ? ? 3.sem_t orange;信號量orange控制女兒可吃的橙子是,初始為0,因為開始盤子里沒橙子。
注:互斥量work_mutex只為printf輸出時能夠保持一致,可忽略。
?
?
#include "pthread.h"
#include "sched.h"
#include "semaphore.h"
#include "stdio.h"
#include "windows.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){
?
(&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);
}
?
來自 <https://blog.csdn.net/lovecodeless/article/details/24919511>
總結
以上是生活随笔為你收集整理的【C/C++多线程编程之七】pthread信号量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 互联网日报 | 4月7日 星期三 | 雷
- 下一篇: 【C/C++多线程编程之八】pthrea