现在的位置: 首页 > 综合 > 正文

Linux c 信号量

2017年12月14日 ⁄ 综合 ⁄ 共 4181字 ⁄ 字号 评论关闭

信号量(通过进程通信实现进程间的同步)

          信号量(semaphore)信号灯

                 信号量是共享内存整数数组.根据需要定义指定的数组长度

                       信号量就是根据数组中的值,决定阻塞还是解除阻塞

编程模型:

1.       创建或者得到信号量 semget

2.       初始化信号量中指定下标的值 semctl

3.       根据信号量阻塞或者解除阻塞 semop

4.       删除信号量 semctl

 

案例:

       A:                                 B:

           创建信号量                          得到信号量

           初始化信号量                        解除阻塞

           根据信号量阻塞

           删除信号量

 

        int semget(key_t key,

                                   int nums,//信号量数组个数

                                   int flags);//信号量的创建标记

                                                                             //创建IPC_CREAT|IPC_EXCL|0666

                                                                             //打开0

                     返回:  -1:失败

                               >=0:成功返回信号量的ID

         

         

                     int semctl(int semid,

                                          intnums,//对IPC_RMID无意义

                                          intcmd,//SETVAL(信号量值) IPC_RMID

                                          ...);//对IPC_RMID无意义

             参数:   
semid:信号集的标识符,即是信号表的索引。
semnum:信号集的索引,用来存取信号集内的某个信号。
cmd:需要执行的命令,有效值有 需要使用联合体semun赋值

               

            union  semun{

                int  val;

                struct semid_ds *buf;

                unsigned short  *array;

                struct seminfo   *_buf;

            };//需要自己定义该联合体,根据需要定义,需要那个字段就可以只定义那个

                                                                                   

                     int semop(

                                   int semid,//信号量ID

                                   struct sembuf*op,//对信号量的操作.操作可以是数组多个

                                   size_tnums,//第二个参数的个数

                            );

                     返回:

                                   -1:时失败

                                    0:成功         

 

                     struct  sembuf

                     {

                            int sem_num;//下标

                            int sem_op;

                            int sem_flg;//建议为0.

                     }

                    sem_op:
前提条件信号量是unsigned short int;
不能<0.
-:够减,则semop马上返回,不够减,则阻塞.
+:执行+操作
0:判定信号量>0,则阻塞,直到为0
               控制进程的搭配方式:
+(解除阻塞) -(阻塞)
0(阻塞)     -(解除阻塞)

 

代码:

semA:

 

#include<stdio.h>

#include<unistd.h>

#include<sys/ipc.h>

#include<sys/sem.h>

#include<stdlib.h>

#include<signal.h>

 

int  semid;

void  deal(int s)

{

//4.删除信号量

printf(“删除信号量…”);

semctl(semid,0,IPC_RMID , 0);

printf(“信号量已删除”);

exit( -1 );

     

}

union  semun{

                int  val;

                struct semid_ds *buf;

                unsigned short  *array;

                struct seminfo   *_buf;

            };

 

void  main()

{

    

     key_t key;

     union semun  v; //2.2定义初始化值

     int r;

     //3.1定义一个操作结构体

     struct sembuf op[1]; //定义了两个操作

     signal(SIGINT , deal);

     //1.创建信号量

     key=ftok(“.” , 99);

     if(key == -1) printf(“ftok err :%m\n”) ,exit(-1);

     semid=semget(kay,1 /*信号量数组个数*/ , IPC_CREAT | IPC_EXCL | 0666);

     if( semget == -1) printf(“get err %m\n”) ,exit(-1);

    

     //2.初始化信号量

     //2.1定义一个联合体

     v.val=2;

     r=semctl(semid , 0 , SETVAL , v); //设置信号量的值

     if(r== -1) printf(“初始化失败:%m\n”) , exit(-1);

     //3.对信号量阻塞操作

     op[0].sem_num=0;  //信号量的下标

     op[0].sem_op= 1;   //信号量操作单位与类型

     op[0].sem_flg=0;    //操作标记  IPC_NOWAIT(信号量值够不够减都返回 不阻塞)

                       //SEM_UNDO    建议为0;

     while(1)

{

         r=semop(semid , op ,1);

         printf(“信号量阻塞-1”);

}

 

        

}

//semop操作减一 ,信号量值大于0,semop执行返回,信号量值等于0时,semop操作阻塞等待,直到信号量值大于0,在进行该操作

 

semB:

 

#include<stdio.h>

#include<unistd.h>

#include<sys/ipc.h>

#include<sys/sem.h>

#include<stdlib.h>

 

union  semun{

                int  val;

                struct semid_ds *buf;

                unsigned short  *array;

                struct seminfo   *_buf;

            };

 

void  main()

{

     int semid;

     key_t key;

     int r;

     //3.1定义一个操作结构体

     struct sembuf op[1]; //定义了两个操作

     signal(SIGINT , deal);

     //1.得到信号量

     key=ftok(“.” , 99);

     if(key == -1) printf(“ftok err :%m\n”) ,exit(-1);

     semid=semget(kay,1 /*信号量数组个数*/ ,0);

     if( semget == -1) printf(“get err %m\n”) ,exit(-1);

    

  

     //3.对信号量阻塞操作

     op[0].sem_num=0;  //信号量的下标

     op[0].sem_op= +1;   //信号量操作单位与类型

     op[0].sem_flg=0;    //操作标记  IPC_NOWAIT(信号量值够不够减都返回 不阻塞)

                       //SEM_UNDO    建议为0;

     while(1)

{

         r=semop(semid , op ,1);

         sleep(1);

}

 

       

}

 

//进程semA进行信号量阻塞-1  semB进行信号量接触阻塞+1 , semB进程控制semA进程的执行

 

                    

                                          

抱歉!评论已关闭.