【Linux】 信號量

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()剩下的部分

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章