日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux环境编程之同步(四):Posix信号量

發布時間:2024/4/15 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux环境编程之同步(四):Posix信号量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

信號量是一種用于提供不同進程間或一個給定進程的不同線程間同步手段的原語。有三種類型:Posix有名信號量,使用Posix IPC名字標識。Posix基于內存的信號量,存放在共享內存區中;System V信號量。在內核中維護。

這三種信號量都可用于進程間或線程間的同步。


圖1 由兩個進程使用的一個二值信號量


圖2 由兩個進程使用的一個Posix有名二值信號量


圖3 由一個進程內的兩個線程共享的基于內存的信號量

一個進程可以在某個信號量上運行的三種操作:

1、創建一個信號量,這要求調用者指定初始值,對于二值信號量來說。它一般是1,也但是0。

2、等待一個信號量,該操作會測試這個信號量的值。假設小于0,就堵塞。也稱為P操作。

3、掛出一個信號量。該操作將信號量的值加1,也稱為V操作。

信號量、相互排斥鎖和條件變量之間的三個差異:

1、相互排斥鎖必須總是給它上鎖的線程解鎖,信號量的掛出卻不必由運行過它的等待操作的同一線程運行。

2、相互排斥鎖要么被鎖住,要么被解開。

3、既然信號量有一個與之關聯的狀態。那么信號量掛出操作總是被記住。

然而當向一個條件變量發送信號時。假設沒有線程等待在該條件變量上。信號丟失。


Posix提供兩類信號量:有名信號量和基于內存的信號量(也稱無名信號量)。

使用函數例如以下:


#include <semaphore.h> /*sem_open創建一個新的有名信號量或打開一個已存在的有名信號量,value參數指定信號量的初始值。返回值是一個指向某個sem_t數據類型的指針,用作其它函數的參數*/ sem_t *sem_open(const char *name, int oflag, .../*mode_t mode, unsigned int value*/); int sem_close(sem_t *sem); /*一個進程終止時,內核對其上仍打開著的全部信號量自己主動運行關閉操作*/ int sem_unlink(const char *name); /*sem_unlink函數:當引用計數大于0時,name就能從文件系統中刪除,然而信號量的析構卻要等到最后一個sem_close發生時為止*/ int sem_wait(sem_t *sem); /*測試所指定信號量的值,大于0。將它減1并返回,等于0,調用線程休眠。直到該值大于0,將它減1,函數隨后返回*/ int sem_trywait(sem_t *sem); /*所指定信號量值為0時,不休眠,而是返回一個EAGAIN錯誤*/ int sem_post(sem_t *sem); int sem_getvalue(sem_t *sem, int *valp);/* 由valp指向的整數中返回所指定信號量的當前值。

*/

semcreate程序:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h>#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)int main(int argc, char **argv) {int c, flags;sem_t *sem;unsigned int value;flags = O_RDWR | O_CREAT;value = 1;while((c = getopt(argc, argv, "ei:")) != -1){switch(c){case 'e':flags |= O_EXCL;case 'i':value = atoi(optarg);break; } }if(optind != argc - 1){printf("usage:semcreate [-e] [-i initalvalue] <name>\n"); return -1;}sem = sem_open(argv[optind], flags, FILE_MODE, value);sem_close(sem);exit(0); }semunlink程序:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char **argv) {if(argc != 2){printf("usage:semunlink <name>.\n"); return -1;}sem_unlink(argv[1]);exit(0); }semgetvalue程序:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char **argv) {sem_t *sem;int val;if(argc != 2){printf("usage:semgetvalue <name>.\n"); return -1;}sem = sem_open(argv[1], 0);sem_getvalue(sem, &val);printf("value = %d\n", val);exit(0); } semwait程序:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char **argv) {sem_t *sem;int val;if(argc != 2){printf("usage: semwait <name>"); return -1;}sem = sem_open(argv[1], 0);sem_wait(sem);sem_getvalue(sem, &val);printf("pid %ld has semaphore, value = %d\n", (long)getpid(), val);pause(); /*block until killed*/exit(0); }sempost程序:

#include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char **argv) {sem_t *sem;int val;if(argc != 2){printf("usage:sempost <name>\n"); return -1;}sem = sem_open(argv[1], 0);sem_post(sem);sem_getvalue(sem, &val);printf("value = %d\n", val);exit(0); }Posix基于內存的信號量,由應用程序分配信號量的內存空間(也就是分配一個sem_t數據類型的內存空間),然后由系統初始化它們的值。

#include <stmaphore.h> int sem_init(sem_t *sem, int shared, unsigned int value); /*出錯返回-1*/ int sem_destroy(sem_t *sem); <span style="white-space:pre"> </span>/*成功返回0,出錯返回-1*/基于內存的信號量是由sem_init初始化的,sem參數指向應用程序必須分配的sem_t變量。假設shared為0,那么待初始化的信號量是在同一進程的各個線程間共享的,否則該信號量是在進程間共享的。

當不須要使用與有名信號量關聯的名字時,可改用基于內存的信號量。

彼此無親緣關系的不同進程須要使用信號量時,通常使用有名信號量。其名字就是各個進程標識信號量的手段。基于內存信號量至少具有進程持續性,然而它們真正的持續性卻取決于存放信號量的內存區的類型。

僅僅要含有某個基于內存信號量的內存區保持有效,該信號量就一直存在。



進程間共享信號量

進程間共享基于內存信號量的規則非常easy:信號量本身必須駐留在由全部希望共享它的進程所共享的內存區中,并且sem_init的第二個參數必須是1。

有名信號量,不同進程總是可以訪問同一個有名信號量。僅僅要它們在調用sem_open時指定同樣的名字就可以。


信號量限制

Posix定義了兩個信號量限制:

SEM_NSEMS_MAX 一個進程可同一時候打開著的最大信號數

SEM_VALUE_MAX 一個信號量的最大值

這兩個常值定義在<unistd.h>頭文件里。可在運行時通過sysconf函數獲取。






轉載于:https://www.cnblogs.com/xfgnongmin/p/10651200.html

總結

以上是生活随笔為你收集整理的Linux环境编程之同步(四):Posix信号量的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。