【Linux系统编程】POSIX无名信号量
生活随笔
收集整理的這篇文章主要介紹了
【Linux系统编程】POSIX无名信号量
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
00. 目錄
文章目錄
- 00. 目錄
- 01. 信號量概述
- 02. 相關(guān)函數(shù)
- 2.1 初始化信號量
- 2.2 銷毀信號量
- 2.3 信號量P操作(減1)
- 2.4 信號量V操作(加1)
- 2.5 獲取信號量的值
- 03. 信號量示例
- 04. 附錄
01. 信號量概述
信號量廣泛用于進程或線程間的同步和互斥,信號量本質(zhì)上是一個非負的整數(shù)計數(shù)器,它被用來控制對公共資源的訪問。
編程時可根據(jù)操作信號量值的結(jié)果判斷是否對公共資源具有訪問的權(quán)限,當(dāng)信號量值大于 0 時,則可以訪問,否則將阻塞。PV 原語是對信號量的操作,一次 P 操作使信號量減1,一次 V 操作使信號量加1。
信號量主要用于進程或線程間的同步和互斥這兩種典型情況。
信號量用于互斥:
信號量用于同步:
在 POSIX 標準中,信號量分兩種,一種是無名信號量,一種是有名信號量。無名信號量一般用于線程間同步或互斥,而有名信號量一般用于進程間同步或互斥。它們的區(qū)別和管道及命名管道的區(qū)別類似,無名信號量則直接保存在內(nèi)存中,而有名信號量要求創(chuàng)建一個文件。
注意:
編譯信號量操作函數(shù)時,需要加上參數(shù)**-lpthread**。
信號量數(shù)據(jù)類型為:sem_t。
02. 相關(guān)函數(shù)
2.1 初始化信號量
#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value); 功能:創(chuàng)建一個信號量并初始化它的值。一個無名信號量在被使用前必須先初始化。 參數(shù):sem:信號量的地址。pshared:等于 0,信號量在線程間共享(常用);不等于0,信號量在進程間共享。value:信號量的初始值。 返回值:成功:0失敗: - 12.2 銷毀信號量
#include <semaphore.h>int sem_destroy(sem_t *sem); 功能:刪除 sem 標識的信號量。 參數(shù):sem:信號量地址。 返回值:成功:0失敗: - 12.3 信號量P操作(減1)
#include <semaphore.h>int sem_wait(sem_t *sem); 功能:將信號量的值減 1。操作前,先檢查信號量(sem)的值是否為 0,若信號量為 0,此函數(shù)會阻塞,直到信號量大于 0 時才進行減 1 操作。 參數(shù):sem:信號量的地址。 返回值:成功:0失敗: - 1int sem_trywait(sem_t *sem); ? 以非阻塞的方式來對信號量進行減 1 操作。 ? 若操作前,信號量的值等于 0,則對信號量的操作失敗,函數(shù)立即返回。int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); ? 限時嘗試將信號量的值減 1 ? abs_timeout:絕對時間abs_timeout補充說明
struct timespec {time_t tv_sec; /* seconds */ // 秒long tv_nsec; /* nanosecondes*/ // 納秒 }time_t cur = time(NULL); //獲取當(dāng)前時間。 struct timespec t; //定義timespec 結(jié)構(gòu)體變量t t.tv_sec = cur + 1; // 定時1秒 sem_timedwait(&cond, &t);2.4 信號量V操作(加1)
#include <semaphore.h>int sem_post(sem_t *sem); 功能:將信號量的值加 1 并發(fā)出信號喚醒等待線程(sem_wait())。 參數(shù):sem:信號量的地址。 返回值:成功:0失敗:-12.5 獲取信號量的值
#include <semaphore.h>int sem_getvalue(sem_t *sem, int *sval); 功能:獲取 sem 標識的信號量的值,保存在 sval 中。 參數(shù):sem:信號量地址。sval:保存信號量值的地址。 返回值:成功:0失敗:-103. 信號量示例
信號量用于互斥實例
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <semaphore.h>sem_t sem; //信號量void printer(char *str) {sem_wait(&sem);//減一while(*str){putchar(*str); fflush(stdout);str++;sleep(1);}printf("\n");sem_post(&sem);//加一 }void *thread_fun1(void *arg) {char *str1 = "hello";printer(str1); }void *thread_fun2(void *arg) {char *str2 = "world";printer(str2); }int main(void) {pthread_t tid1, tid2;sem_init(&sem, 0, 1); //初始化信號量,初始值為 1//創(chuàng)建 2 個線程pthread_create(&tid1, NULL, thread_fun1, NULL);pthread_create(&tid2, NULL, thread_fun2, NULL);//等待線程結(jié)束,回收其資源pthread_join(tid1, NULL);pthread_join(tid2, NULL); sem_destroy(&sem); //銷毀信號量return 0; }執(zhí)行結(jié)果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out hello world deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$信號量用于同步
#include <stdio.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h>sem_t sem_g,sem_p; //定義兩個信號量 char ch = 'a';void *pthread_g(void *arg) //此線程改變字符ch的值 {while(1){sem_wait(&sem_g);ch++;sleep(1);sem_post(&sem_p);} }void *pthread_p(void *arg) //此線程打印ch的值 {while(1){sem_wait(&sem_p);printf("%c",ch);fflush(stdout);sem_post(&sem_g);} }int main(int argc, char *argv[]) {pthread_t tid1,tid2;sem_init(&sem_g, 0, 0); //初始化信號量sem_init(&sem_p, 0, 1);pthread_create(&tid1, NULL, pthread_g, NULL);pthread_create(&tid2, NULL, pthread_p, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0; }測試結(jié)果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out abcdefghijklmnopqr^C deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$04. 附錄
總結(jié)
以上是生活随笔為你收集整理的【Linux系统编程】POSIX无名信号量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux系统编程】互斥锁
- 下一篇: 【Linux系统编程】POSIX有名信号