Linux GCC 信号量

来源:互联网 发布:最好的手机优化软件 编辑:程序博客网 时间:2024/06/01 12:10

简述信号量的创建、初始化、定义原子操作结构体、pv使用。
1.信号量创建
类似于共享内存的创建方式
int semid = semget(key,size,flag)
例如: int semid = semget(1000,1,IPC_CREAT|0600);
2.信号量的初始化
类似于解锁操作,先把锁释放
int ret = semctl(semid,0,SETVAL,1);
3.原子操作结构体

    struct sembuf sopp,sopv;    memset(&sopp,0,sizeof(sopp));    memset(&sopv,0,sizeof(sopv));    //P  -1操作结构体    sopp.sem_num=0;    sopp.sem_op=-1;    sopp.sem_flg=SEM_UNDO;    //V +1操作结构体    sopv.sem_num=0;    sopv.sem_op=1;    sopv.sem_flg=SEM_UNDO;

4.实例:
fork创建父子进程,分别计算加法,模拟并发操作,在使用信号量的情形下结果符合预期。如果不加入信号量,那么就没有原子操作结果不会符合预期

#include "func.h"#define N 1int main(int argc,char* argv[]){    int sem;    sem=semget(IPC_PRIVATE,1,IPC_CREAT|0600);    int ret=semctl(sem,0,SETVAL,1);    int shmid;    shmid=shmget(1000,4096,IPC_CREAT|0600);    int* p;    p=(int*)shmat(shmid,NULL,0);    *p=0;    int i;    struct sembuf sopp,sopv;    memset(&sopp,0,sizeof(sopp));    memset(&sopv,0,sizeof(sopv));    sopp.sem_num=0;    sopp.sem_op=-1;    sopp.sem_flg=SEM_UNDO;    sopv.sem_num=0;    sopv.sem_op=1;    sopv.sem_flg=SEM_UNDO;    if(!fork())    {        for(i=0;i<N;i++)        {            //通知信号量执行sopp结构体定义的操作,p -1操作,singal变为0            semop(sem,&sopp,1);            int singal=semctl(sem,0,GETVAL);            printf("c: p=%d  v=%d  singal=%d\n",sopp.sem_op,sopv.sem_op,singal);            *p=*p+1;            //通知信号量执行sopv结构体 , v +1  ,singa变为1            semop(sem,&sopv,1);            singal=semctl(sem,0,GETVAL);            printf("c: p=%d  v=%d  singal=%d\n",sopp.sem_op,sopv.sem_op,singal);        }        exit(0);    }else{        for(i=0;i<N;i++)        {            semop(sem,&sopp,1);            *p=*p+1;            semop(sem,&sopv,1);        }        wait(NULL);        printf("the value %d\n",*p);        return 0;    }}