嵌入式Linux熱門培訓內容之Linux信號量

時間:2018-12-13 17:33:33

問:什么是信號量?

答:信號量是一個特殊的整數,最大值是32767

問:為什么需要信號量?

答:信號量是用來解決線程間同步或互斥的一種機制

舉個栗子:

我們把信號量舉栗為一個廁所,假設廁所有4個坑,有10個人想上大號,那么有6個人就需要在外面等待。

假設就只有一個坑,有兩個人想上廁所,那就有一個人在外面等待,就變成了0,1信號量,相當于互斥鎖,我上廁所的時候,你就得等著,你上廁所的時候,我就得等著。

操作相關函數:

創建信號量:

  創建或者打開一個信號量,需要使用sem_open()函數,函數原形如下:

  sem_t sem_open(const char * name, int oflag, mode_t mode, unsigned int value)

  返回值sem_t 是一個結構,如果函數調用成功,則返回指向這個結構的指針,里面裝著當前信號量的資源數。

  參數name,就是信號量的名字,兩個不同的進程通過同一個名字來進行信號量的傳遞。

  參數oflag,當他是O_CREAT時,如果name給出的信號量不存在,那么創建,此時必須給出mode和vaule。

  參數mode,指出信號量名字的權限

  參數vaule,信號量的初始值

關閉信號量:

  關閉有名信號量 sem_close(sem_t *sem)

  這個函數只有一個參數,意義也非常明顯,就是指信號量的名字。

信號量操作:

  P操作:使用的函數是sem_wait(sem_t *sem)

  如果信號量的值大于零,sem_wait函數將信號量減一,并且立即返回。如果信號量的值小于零,那么該進程會被阻塞在原地。

  V操作:使用的函數是sem_post(sem_t *sem)

  當一個進程使用完某個信號量時,他應該調用sem_post函數來告訴系統收回資源。

  sem_post函數和sem_wait函數的功能剛好相反,他會把指定的信號量加一

刪除有名信號量:

  當使用完有名信號后,需要調用函數sem_unlink來釋放資源。

  函數原形:int sem_unlink(const char *name)

代碼例子:

進程1

#include <stdio.h>

#include <stdlib.h>

#include <semaphore.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>

int main()

{

    sem_t *sem_test;

    sem_test = sem_open("sem_test_01", O_CREAT, 0644, 0); 

    if(sem_test < 0)

    {   

          printf("create sem error errno=%d\n",errno);

          exit(-1);

    }   

    printf("process TMAC set to waiting……\n");

    printf("This is 1\n");

    sem_wait(sem_test);

    printf("This is 3\n");

    sem_post(sem_test);

    printf("process TMAC GO OVER \n");

    sem_close(sem_test);

    sem_unlink("sem_test_01");

    return 0;

}

進程2、

#include<stdio.h>

#include<stdlib.h>

#include<semaphore.h>

#include<errno.h>

#include<sys/stat.h>

#include<fcntl.h>

int main()

{

    sem_t *sem_test;

    sem_test = sem_open("sem_test_01",0);

    if(sem_test < 0)

    {

        printf("process Paul creat sem error errno=%d\n",errno);

        exit(-1);

    }

    printf("process Paul 2\n");

    sem_post(sem_test);

    printf("process Paul GO OVER!\n");

    sem_close(sem_test);

    sem_unlink("sem_test_01");

    return 0;

}

? 江苏快3号码表