【Linux系统编程】POSIX有名信号量
生活随笔
收集整理的這篇文章主要介紹了
【Linux系统编程】POSIX有名信号量
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 相關(guān)函數(shù)
- 2.1 創(chuàng)建有名信號(hào)量
- 2.2 關(guān)閉有名信號(hào)量
- 2.3 刪除有名信號(hào)量
- 2.4 信號(hào)量P操作
- 2.5 信號(hào)量V操作
- 03. 程序示例
- 04. 附錄
01. 概述
在 POSIX 標(biāo)準(zhǔn)中,信號(hào)量分兩種,一種是無(wú)名信號(hào)量,一種是有名信號(hào)量。無(wú)名信號(hào)量一般用于線程間同步或互斥,而有名信號(hào)量一般用于進(jìn)程間同步或互斥。它們的區(qū)別和管道及命名管道的區(qū)別類(lèi)似,無(wú)名信號(hào)量則直接保存在內(nèi)存中,而有名信號(hào)量要求創(chuàng)建一個(gè)文件。
02. 相關(guān)函數(shù)
2.1 創(chuàng)建有名信號(hào)量
#include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #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);Link with -pthread. 功能:創(chuàng)建一個(gè)有名信號(hào)量。 參數(shù):name:信號(hào)量文件名。注意,不能指定路徑名。因?yàn)橛忻盘?hào)量,默認(rèn)放在/dev/shm 里 flags:sem_open() 函數(shù)的行為標(biāo)志。mode:文件權(quán)限(可讀、可寫(xiě)、可執(zhí)行)的設(shè)置。value:信號(hào)量初始值。 返回值:成功:信號(hào)量的地址失敗:SEM_FAILED2.2 關(guān)閉有名信號(hào)量
#include <semaphore.h> int sem_close(sem_t *sem); Link with -pthread. 功能:關(guān)閉有名信號(hào)量。 參數(shù):sem:指向信號(hào)量的指針。 返回值:成功:0失敗:-12.3 刪除有名信號(hào)量
#include <semaphore.h>int sem_unlink(const char *name); 功能:刪除有名信號(hào)量的文件。 參數(shù):name:有名信號(hào)量文件名。 返回值:成功:0失敗:-12.4 信號(hào)量P操作
#include <semaphore.h>int sem_wait(sem_t *sem); 功能:將信號(hào)量的值減 1。操作前,先檢查信號(hào)量(sem)的值是否為 0,若信號(hào)量為 0,此函數(shù)會(huì)阻塞,直到信號(hào)量大于 0 時(shí)才進(jìn)行減 1 操作。 參數(shù):sem:信號(hào)量的地址。 返回值:成功:0失敗: - 1int sem_trywait(sem_t *sem); ? 以非阻塞的方式來(lái)對(duì)信號(hào)量進(jìn)行減 1 操作。 ? 若操作前,信號(hào)量的值等于 0,則對(duì)信號(hào)量的操作失敗,函數(shù)立即返回。int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); ? 限時(shí)嘗試將信號(hào)量的值減 1 ? abs_timeout:絕對(duì)時(shí)間abs_timeout補(bǔ)充說(shuō)明
struct timespec {time_t tv_sec; /* seconds */ // 秒long tv_nsec; /* nanosecondes*/ // 納秒 }time_t cur = time(NULL); //獲取當(dāng)前時(shí)間。 struct timespec t; //定義timespec 結(jié)構(gòu)體變量t t.tv_sec = cur + 1; // 定時(shí)1秒 sem_timedwait(&cond, &t);2.5 信號(hào)量V操作
#include <semaphore.h>int sem_post(sem_t *sem); 功能:將信號(hào)量的值加 1 并發(fā)出信號(hào)喚醒等待線程(sem_wait())。 參數(shù):sem:信號(hào)量的地址。 返回值:成功:0失敗:-103. 程序示例
示例一:有名信號(hào)量實(shí)現(xiàn)進(jìn)程間互斥功能
#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); //信號(hào)量減一while(*str!='\0'){putchar(*str); fflush(stdout);str++;sleep(1);}printf("\n"); sem_post(sem); //信號(hào)量加一 }int main(int argc, char *argv[]) {pid_t pid;sem_t *sem = NULL;pid = fork(); //創(chuàng)建進(jìn)程if(pid<0){ //出錯(cuò)perror("fork error");}else if(pid == 0){ //子進(jìn)程//跟open()打開(kāi)方式很相似,不同進(jìn)程只要名字一樣,那么打開(kāi)的就是同一個(gè)有名信號(hào)量sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1); //信號(hào)量值為 1if(sem == SEM_FAILED){ //有名信號(hào)量創(chuàng)建失敗perror("sem_open");return -1;}char *str1 = "hello";printer(sem, str1); //打印sem_close(sem); //關(guān)閉有名信號(hào)量_exit(1);}else if(pid > 0){ //父進(jìn)程//跟open()打開(kāi)方式很相似,不同進(jìn)程只要名字一樣,那么打開(kāi)的就是同一個(gè)有名信號(hào)量sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1); //信號(hào)量值為 1if(sem == SEM_FAILED){//有名信號(hào)量創(chuàng)建失敗perror("sem_open");return -1;}char *str2 = "world";printer(sem, str2); //打印sem_close(sem); //關(guān)閉有名信號(hào)量wait(pid, NULL); //等待子進(jìn)程結(jié)束}sem_unlink("name_sem");//刪除有名信號(hào)量return 0; }測(cè)試結(jié)果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out hello world deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$示例二: 有名信號(hào)量實(shí)現(xiàn)進(jìn)程間同步功能(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; }刪除有名信號(hào)量的代碼:
#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"); //刪除信號(hào)量文件sem_print1sem_del("sem_print2"); //刪除信號(hào)量文件sem_print2return 0; }04. 附錄
總結(jié)
以上是生活随笔為你收集整理的【Linux系统编程】POSIX有名信号量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Linux系统编程】POSIX无名信号
- 下一篇: 【Linux系统编程】Linux进程管理