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

歡迎訪問 生活随笔!

生活随笔

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

linux

【Linux系统编程】进程同步与互斥:POSIX有名信号量

發布時間:2024/4/21 linux 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux系统编程】进程同步与互斥:POSIX有名信号量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在 POSIX 標準中,信號量分兩種,一種是無名信號量,一種是有名信號量。無名信號量一般用于線程間同步或互斥,而有名信號量一般用于進程間同步或互斥。它們的區別和管道及命名管道的區別類似,無名信號量則直接保存在內存中,而有名信號量要求創建一個文件。前面我們學習了無名信號量的使用(詳情請看《無名信號量》),這里我們學習有名信號量的使用。


1)創建一個有名信號量

所需頭文件:

#include <fcntl.h>

#include <sys/stat.h>

#include <semaphore.h>


當有名信號量存在時使用:
sem_t *sem_open(const char *name, int oflag);


當有名信號量不存在時使用:
sem_t *sem_open(const char *name, int oflag,?mode_t mode, unsigned int value);

功能:

創建一個有名信號量。

參數:

name:信號量文件名。注意,不能指定路徑名。因為有名信號量,默認放在/dev/shm?里,如下圖:

flags:sem_open() 函數的行為標志。

mode:文件權限(可讀、可寫、可執行)的設置。

value:信號量初始值。

返回值:

成功:信號量的地址

失敗:SEM_FAILED


2)關閉有名信號量

所需頭文件:

#include <semaphore.h>


int sem_close(sem_t *sem);
功能:

關閉有名信號量。

參數:

sem:指向信號量的指針。

返回值:

成功:0

失敗:-1


3)刪除有名信號量文件

所需頭文件:

#include <semaphore.h>


int sem_unlink(const char *name);
功能:

刪除有名信號量的文件。

參數:

name:有名信號量文件名。

返回值:

成功:0

失敗:-1


4)信號量 PV 操作

用法和《POSIX 無名信號量》一樣,詳情請點此鏈接。


有名信號量實現進程間互斥功能:

#include<stdio.h> #include<semaphore.h> #include<fcntl.h> #include<unistd.h> #include<sys/stat.h> #include<sys/types.h>void printer(sem_t *sem, char *str) {sem_wait(sem); //信號量減一while(*str!='\0'){putchar(*str); fflush(stdout);str++;sleep(1);}printf("\n"); sem_post(sem); //信號量加一 }int main(int argc, char *argv[]) {pid_t pid;sem_t *sem = NULL;pid = fork(); //創建進程if(pid<0){ //出錯perror("fork error");}else if(pid == 0){ //子進程//跟open()打開方式很相似,不同進程只要名字一樣,那么打開的就是同一個有名信號量sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1); //信號量值為 1if(sem == SEM_FAILED){ //有名信號量創建失敗perror("sem_open");return -1;}char *str1 = "hello";printer(sem, str1); //打印sem_close(sem); //關閉有名信號量_exit(1);}else if(pid > 0){ //父進程//跟open()打開方式很相似,不同進程只要名字一樣,那么打開的就是同一個有名信號量sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1); //信號量值為 1if(sem == SEM_FAILED){//有名信號量創建失敗perror("sem_open");return -1;}char *str2 = "world";printer(sem, str2); //打印sem_close(sem); //關閉有名信號量wait(pid, NULL); //等待子進程結束}sem_unlink("name_sem");//刪除有名信號量return 0; }


運行結果如下:


有名信號量實現進程間同步功能(print2 先打印,再到 print1 打印):

print1.c 代碼如下:

#include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <semaphore.h> #include <stdio.h>void print(sem_t *print1, sem_t *print2) {int i = 0;while(1){sem_wait(print1);i++;printf("int print1 i = %d\n", i);sem_post(print2);} }int main(int argc, char **argv) { sem_t *print1, *print2;print1 = sem_open("sem_print1", O_CREAT, 0777, 0); if(SEM_FAILED == print1){perror("sem_open");}print2 = sem_open("sem_print2", O_CREAT, 0777, 1); if(SEM_FAILED == print2){perror("sem_open");}print(print1, print2);return 0; }


print2.c 代碼如下:

#include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <semaphore.h> #include <stdio.h>void print(sem_t *print1, sem_t *print2) {int i = 0;while(1){sem_wait(print2);i++;printf("in print2 i = %d\n", i);sleep(1);sem_post(print1);} }int main(int argc, char **argv) { sem_t *print1, *print2;print1 = sem_open("sem_print1", O_CREAT, 0777, 0); if(SEM_FAILED == print1){perror("sem_open");}print2 = sem_open("sem_print2", O_CREAT, 0777, 1); if(SEM_FAILED == print2){perror("sem_open");}print(print1, print2);return 0; }


刪除有名信號量示例代碼如下:

#include <semaphore.h> #include <stdio.h>void sem_del(char *name) {int ret;ret = sem_unlink(name);if(ret < 0){perror("sem_unlink");} }int main(int argc, char **argv) {sem_del("sem_print1"); //刪除信號量文件sem_print1sem_del("sem_print2"); //刪除信號量文件sem_print2return 0; }


makefile 代碼如下:

all:gcc sem_del.c -o sem_del -lpthreadgcc print1.c -o print1 -lpthreadgcc print2.c -o print2 -lpthread clean:rm sem_del print1 print2

運行程序時,先把有名信號量刪除(sem_del),再分別運行 print1 和 print2:


總結

以上是生活随笔為你收集整理的【Linux系统编程】进程同步与互斥:POSIX有名信号量的全部內容,希望文章能夠幫你解決所遇到的問題。

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