1.信號量結構體
typedef union
{
char __size[__SIZEOF_SEM_T];
long int __align;
} sem_t;
2.常用函數
/*breaf: 創建一個信號量*/
//pshared 爲0代表此信號量爲局部信號量
int sem_init(sem_t *sem, int pshared, unsigned int value);
/*breaf: 信號量值(初值必須大於1)減1 */
int sem_wait(sem_t *sem);
/*breaf: 信號量值加1 */
int sem_post(sem_t *sem);
/*breaf: 清理信號量 */
int sem_destroy(sem_t *sem);
3.簡單示例(涉及線程部分,可看我上一篇博客)
#include "stdio.h"
#include "unistd.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"
#include "semaphore.h"
void *thread_funtion(void *arg);
sem_t bin_sem;
#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int main()
{
int res;
pthread_t a_thread;
void *thread_result;
//1.創建一個局部信號量
res = sem_init(&bin_sem, 0, 0);
if(res != 0){ printf("semphare init fail"); }
//2.創建一個線程
res = pthread_create(&a_thread, NULL, thread_funtion, NULL);
if(res != 0){ printf("error create thread"); }
//3.從鍵盤輸入任意字符
printf("please press keyborad!!! end with button 'end'\r\n ");
while(strncmp("end", work_area, 3) != 0){
fgets(work_area, WORK_SIZE, stdin);//從鍵盤讀取文本,並放入工作區work_area數組之中
sem_post(&bin_sem); //bin_sem+1
}
//4.等待線程結束
printf("\n thread waiting for finish \n");
res = pthread_join(a_thread, &thread_result);//thread_result == Thread_A return "Thank you using CPU!!!!!!"
if(res != 0){ printf("error thread join "); }
printf("thread joined, it returned %s ", (char*)thread_result);
//5.銷燬信號量
sem_destroy(&bin_sem);
}
void *thread_funtion(void* arg)
{
printf("111\n");
sem_wait(&bin_sem);
printf("222");
while(strncmp("end", work_area, 3) != 0){//任意按鍵輸入,以end鍵結束
printf("you have input %zu characters\n", strlen(work_area)-1); //%zu 輸出size_t類型的數據
sem_wait(&bin_sem);
}
//printf("333");
}
4.運行結果
5.結合代碼,分析上述流程。
【1】創建信號量(初值爲0),線程(線程A)。
【2】main函數的線程(主線程)運行至等待鍵盤輸入字符的地方(打印出了please press keyborad!! end with button 'end'),同時緊接着運行至線程A(打印出了111),但此時鍵盤沒有任何的輸入,信號量爲0,於是線程A運行至sem_wait(&bin_sem);處,由於信號量爲0,於是不會繼續往下執行(沒有打印出222)
【3】鍵盤輸入“abc+回車”,那麼在主線程中則會調用sem_post(&bin_sem)函數,那麼信號量加1,變爲非0值。程序運行至fget()等待鍵盤的輸入
線程A此時停在sem_wait(&bin_sem);由於信號量變爲非0值,那麼就會執行while()裏面的打印函數(打印了you have input 3 characters),然後再調用sem_wait(&bin_sem);於是bin_sem變爲0,線程A則會停在此處(沒有一直打印you have input 3 characters,即可證明)
【4】鍵盤輸入"def+回車",即重複過程上述【3】
【5】鍵盤輸入"end+回車",主線程退出while,並且等待線程A結束(即退出線程A的while),最後打印main()剩下的部分