大家好,今天主要和大家聊一聊,如何使用信号量的方法。

目录
第一: 父子进程相隔1s报数一次
第二:利用信号量实现父子进程通信
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。
第一: 父子进程相隔1s报数一次
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>typedef union semun {int val; /* Value for SETVAL */unsigned short *array; /* Array for GETALL, SETALL */
}SEM;//实现两个进程的0~99报数
int main(int argc,char *argv[])
{int i=0;//1、获取键值 ftokkey_t key = ftok(argv[1], 2);if(-1 == key){perror("ftok error\r\n");return 0;}//2、创建信号量集 semgetint semid = semget(key, 2, IPC_CREAT | 0666);if(-1 == semid){perror("semget error\r\n");return 0;}SEM num={0};//3、设置0号信号量的值为1 SETVALnum.val = 1;if(semctl(semid, 0, SETVAL, num) == -1){perror("SETALL error\r\n");return 0;}//4、创建操作方式的结构体 struct sembufstruct sembuf sops[4]={{0,1,0},{0,-1,0},{1,1,0},{1,-1,0}};//5、创建子进程 forkpid_t pid = fork( );if(pid < 0){perror("fork error\r\n");return 0;}else if(0 == pid)//子进程 单数{i=1; //初始为1while(i < 100){//信号1 -1if(semop(semid, &sops[3], 1) == -1){perror("semop 1 -1 error\r\n");return 0;}printf("child:time = %d\r\n",i);// 1 i+=2;sleep(1);//信号0 +1if(semop(semid, &sops[0], 1) == -1){perror("semop 0 +1 error\r\n");return 0;}}exit(0);}else//父进程 双数{while(i < 100){//信号0 -1if(semop(semid, &sops[1], 1) == -1){perror("semop 0 -1 error\r\n");return 0;}printf("father:time = %d\r\n",i); //0 2i+=2;sleep(1);//信号1 +1if(semop(semid, &sops[2], 1) == -1){perror("semop 1 +1 error\r\n");return 0;}}wait(NULL); }return 0;
}

第二:利用信号量实现父子进程通信
//实例2:利用父子进程通信
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <sys/sem.h>union semun
{int val;struct semid_ds *buf;unsigned short *array;struct seminfo* _buf; };int main()
{int ret;int semid;//创建信号量semid = semget(IPC_PRIVATE,1,IPC_CREAT|0644);//初始化信号量、设置信号量union semun arg;arg.val=0;//信号量值为0semctl(semid,0,SETALL,arg);//查询当前信号量的值ret = semctl(semid,0,GETVAL);//GETVAL返回值为信号值printf("val:%d\r\n",ret);//创建子进程pid_t pid;pid = fork();if(pid == 0){//子进程sleep(5);struct sembuf sops={0,1,0};while(1){semop(semid,&sops,1);//P操作printf("--------V------\r\n");sleep(1);}}else{//父进程struct sembuf sops={0,-1,0};while(1){semop(semid,&sops,1);//P操作printf("--------P------\r\n");//信号量0还可以执行最后一次sleep(1);}}semctl(semid,0,IPC_RMID);return 0;
}

总结:信号量就是为了对共享资源进行保护,理解基本实现方法非常重要。
















