• Linux 进程间通信


     1,

       进程通信:在用户空间实现通信时不可能的,通过linux内核通信

       线程间通信: 可以在用户空间实现,可通过全局变量通信

    2,通信方式

       管道通信:无名管道,有名管道(文件系统中有名)

       信号通信:信号(通知)通信包括:信号的发送,信号的接受和信号的处理

          IPC通信:共享内存,消息队列,和信号灯

       以上是的单机模式下的进程通信(只有一个linux内核)

        

       Socket通信:存在于一个网络中两个进程间的通信(两个LINUX内核)

    3,思路:  每种通信方式都是基于文件IO 的思想

        open 

        read

        write

        close

    __________________________________________________________________________________________________

    二:无名管道

        内核的管道是由队列实现(入队和出队)

        在文件IO中创建文件是由open 函数来实现,但它只能创建普通文件,管道文件需要用pipe函数来创建

          

        int  pipe (int fd[2]);    创建管道,微系统调用

        参数: 就是得到的 文件描述符。可见有两个文件 描述符:fd[0],fd[1]; 管道有一个读端fd[0] 和一个写端fd[1] ,不能改变

        返回值: 成功是0,出错时-1;

        

        注意:

          1)管道是创建在内存中的,进程结束,空间释放,管道就不存在了。

          2)管道中的东西,读完就删除了

          3)如果管道中没有东西可读,就会读阻塞。

          4)无名管道不能实现非父子进程(只能是内核中的同一管道)

    #include "unistd.h"
    #include "stdio.h"
    #include "stdlib.h"
    
    int main()
    {
       int fd[2];
       int ret;
       char write_buf[] = "hello linux";
       char read_buf[128] = {0};
       ret =  pipe(fd);
    
       if(ret <0)
       {
         printf("creat process failure
    ");
         return -1;
       }
         printf("creat process success ,fd[0]=%d,fd[1]=%d
    ",fd[0],fd[1]);
    
         write(fd[1],write_buf,sizeof(write_buf));
         read(fd[0],read_buf,128);
         printf("read:%s
    ",read_buf);
        close(fd[0]);
        close(fd[1]);
       return 0;
    
    }
        
    结果:
    creat process success ,fd[0]=3,fd[1]=4
    read:hello linux
    pipe的简单用法

    父子进程:fork();

    pid = fork();

    if (pid>0)   {};    父进程

    if (pid ==0)  {};   子进程

        1)在父进程中,fork返回新创建子进程的进程ID
        2)在子进程中,fork返回0;
        3)如果出现错误,fork返回一个负值;

    getpid();获取当前进程ID

    getppid();获取当前进程的父进程ID

     三:有名管道

        通过管道实现无亲缘关系进程间通信,

        1,创建这个文件节点,不可以通过open 函数,open 函数只能创建普通文件,不能创建特殊文件(管道 -mkdifo ,套接字 -socket ,字符设备文件 -mknod ,块设备文件 -mknod , 符号链接文件 -ln -s, 目录文件 mkdir )

        2,管道文件只有inode 号,不占磁盘块空间,和套接字、字符设备文件、块设备文件一样。 普通文件和符号链接文件及目录文件,不仅有inode 号,还占磁盘空间。

        3,mkfifo  用来创建管道文件的节点,没有在内核中创建管道

              只有通过open函数打开这个文件是才会在内核空间创建管道

        mkfifo

        int  mkfifo (const char *filename,mode_t mode);   创建管道文件

        参数:管道文件名,权限(仍与umask有关),

        返回值:创建成功返回0,失败返回-1

        

    四:信号通信

      信号通信,其实就是内核向用户空间进程发送信号,只有内核才能发送信号,用户空间进程不能发送信号。

      

      信号通信的框架:

      信号的发送:(发送信号进程)  kill  raise  alarm

      信号的处理:(接受信号进程)  pause()   sleep(睡眠)   while(1)

      信号的发送:(发送信号进程)  signal

      1,信号的发送()

        kill :

          头文件:#include  <signal.h>

              #inlcude  <sys/types.h>

          函数:  int kill (pid_t pid,int sig);

          参数:pid : 1,正数:要接受信号的进程的进程号    2,0:信号被发送到所有和PID进程在同一个进程组的进程      3,-1:信号发给所有的进程表中的进程(除了进程号最大的进程外)

             sig :  信号

          返回值:成功 :0;    出错:-1;

          此时kill为函数,kill命令为结束进程 ,kill函数可以实现命令功能

      

        raise :  发信号给自己  ==  kill (getpid(),sig)

    •       头文件:#include  <signal.h>

                 #include <sys/types.h>

    •       函数: int raise (int sig);
    •       参数:sig : 信号
    •       返回值:成功 :0;    出错:-1;

        alarm   :  闹钟信号    定时,只能发送给当前进程

    •        头文件:#include "unsitd.h"
    •        函数:    unsigned int alarm  (insigned int seconds);
    •        参数:    seconds   指定秒数
    •        返回值: 成功:如果调用alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟的剩余时间,负责返回0 ;          出错:-1;

        2,信号的接收

          要想使接收到进程的能接收到信号,进程不能结束;

    •       sleep;
    •       pause:    进程状态为 S(睡眠状态),     与sleep 不同的是,sleep 可以是进程睡眠一段时间,而pause 如果不唤醒,它可以一直睡眠;
    •       while(1);

          

          pause:

    •         头文件:#inlclude "unistd.h"
    •         函数: int  pause (void);
    •         返回值: 成功    :  0  ;出错  :  -1;

        3,信号的处理

         (1)进程的默认处理方式(内核为用户进程设置的默认处理方式)    

    •        忽略
    •        终止进程  
    •        暂停

         (2)自己的处理方式

              自己处理信号的方法告诉内核,这样你的进程收到了这个信号就会采用自己的处理方式

             signal

              头文件: #include "signal.h"

              函数:      void  (*signal (int signum, void (*handler) (int))) (int);

              参数:

                  signum  :   指定信号

                  hangler:     

                        SIG_IGN   :     忽略该信号

                        SIG_DFL   :  采用系统默认方式处理信号 (终止)

                        自定义的信号处理函数指针

              返回值: 成功  :设置之前的信号处理方式 ;               出错 :   -1   ;

                                        自我感觉就像是中断???

     1 #include "sys/types.h"
     2 #include "signal.h"
     3 #include "stdlib.h"
     4 
     5 void myfun()
     6 {
     7    int i;
     8    for(i=0;i<10;i++)
     9     printf("second , i=%d
    ",i);
    10     return;
    11 
    12 }
    13 int main()
    14 {
    15      int i;
    16      i=0;
    17      signal(14,myfun);
    18      printf("alarm before
    ");
    19      alarm(4);
    20      printf("alarm after
    ");
    21 
    22      while(i<10)
    23       {
    24          i++;
    25          sleep(1);
    26         printf("main,i=%d
    ",i);
    27 
    28        }
    29      return 0;
    30 }
    31 ~                                                                                                                
    32 
    33 结果:
    34 alarm before
    35 alarm after
    36 main,i=1
    37 main,i=2
    38 main,i=3
    39 second , i=0
    40 second , i=1
    41 second , i=2
    42 second , i=3
    43 second , i=4
    44 second , i=5
    45 second , i=6
    46 second , i=7
    47 second , i=8
    48 second , i=9
    49 main,i=4
    50 main,i=5
    51 main,i=6
    52 main,i=7
    53 main,i=8
    54 main,i=9
    55 main,i=10
    56    
    信号处理

    IPC通信————》IPC对象 {共享内存,消息队列,信号灯};

    文件IO IPC
    open

    Msg_get     打开或创建消息队列

    Shm_get    创建共享内存

    Sem_get    创建信号灯

    read

    write

    msgsnd   msgrecv    (读   写)

    shmat      shmdt

    semop

    close

    msgctrl

    shmctrl

    semctrl

    五,共享内存

                  共享内存就是一块缓存,类似于用户空间的数组,或malloc函数分配的空间一样

                   1,Shm_get    打开或创建共享内存

          头文件: #include <sys/types.h>

              #include <sys/ipc.h>

              #include <sys/shm.h>

          函数:   int  shmget  (key_t key, int size ,int shmflg);

          参数: key  :    IPC_PRIVATE  或 ftok  的返回值,,,,(在使用返回值时,需要加宏)(     shmid = shmget (key,128,IPC_CREAT | 0777);     )

              size :    共享内存的大小

              shmflg:   同open 函数的权限位,也可用8进制表示法

          返回值:        成功   共享内存标识符——ID——文件描述符 ;      出错   :  -1   ;

          查看IPC对象  :  ipcs -m(查看内核空间共享内存对象)    -q (消息队列)    -s (信号灯)

          删除IPC对象  :       ipcrm  -m   id

          返回值: 共享内存段标识符     IPC 的ID 号

     1 #include "signal.h"
     2 #include "unistd.h"
     3 #include "stdio.h"
     4 #include "stdlib.h"
     5 #include "sys/types.h"
     6 #include "sys/shm.h"
     7 
     8 int main()
     9 {
    10     int shmid;
    11    int pid;
    12 
    13     pid =  ftok("./home/xiaozhao/2.c",'a');
    14     shmid = shmget(pid,128,IPC_CREAT | 0777);
    15 
    16     if(shmid<0)
    17         {
    18            printf("creat share memory failure
    ");
    19            return -1;
    20         }
    21 
    22           printf("craet share meory sucess
    ");    //创建共享内存
    23          system("ipcs -m");
    24         return 0;
    25 
    26 }
    27 
    28 
    29 
    30 
    31 结果:
    32 craet share meory sucess
    33 
    34 ------------ 共享内存段 --------------
    35 键        shmid      拥有者  权限     字节     连接数  状态      
    36 0x00000000 1179648    xiaozhao   600        524288     2          目标       
    37 0x00000000 393217     xiaozhao   600        524288     2          目标       
    38 0x00000000 425986     xiaozhao   600        524288     2          目标       
    39 0x00000000 688131     xiaozhao   600        524288     2          目标       
    40 0x00000000 720900     xiaozhao   600        16777216   2                       
    41 0x00000000 819205     xiaozhao   600        524288     2          目标       
    42 0x00000000 1081350    xiaozhao   600        524288     2          目标       
    43 0x00000000 950279     xiaozhao   600        67108864   2          目标       
    44 0x00000000 1212424    xiaozhao   600        1048576    2          目标       
    45 0x00000000 1376265    xiaozhao   600        524288     2          目标       
    46 0x00000000 1736714    root       777        128        0                       
    47 0xffffffff 1769483    root       777        128        0     
    key 的不同用法

                      {              

              key   的区别

                     1)  使用宏创建的key ,,,始终为0

              2)  ftok   :  创建key 的值

                  char ftok (const  char *path ,char key)

                  参数: 第一个:  文件路径和文件名  ;    第二个 : 一个字符;

                  返回值: 正确返回一个key的值,  错误返回-1;

     

                IPC_PRIVATE  操作时,共享内存的key 值是0;所以使用 ftok 开创建KEY值。  只要KEY 的值是一样的,用户空间的进程通过这个函数打开,则会对内核的同一个IPC对象操作

          }

          

          3,shmat     将共享内存映射到用户空间中

              为了方便用户空间对共享内存的操作,使用地址映射的方式

              

              void *shmat (int shmit ,const void *shmaddr , int shmflg);

                参数: shmat :    ID 号

                    shmaddr:   映射到的地址,NULL为系统自动完成的映射

                    shmflg:    SHM_RDONLY  共享内存只读  ;    默认是0 , 表示共享内存可读写  ;

                返回值: 成功  :  映射后的地址  ;        出错  : NULL;

          

                     shmdt     :   将用户空间进程里的地址映射删除。

                int shmdt (const void *shmaddr);

                参数: shmaddr 共享内存映射后的地址;(就是映射后的返回值

                返回值: 成功  :  0  ;     失败    :   -1  ;

        

          共享内存的特点: 

            1) 共享内存创建之后,一直存在于内核之中,直到被删除或系统关闭

            2)共享内存和管道不一样,读取后,内容仍在其共享内存中。

             shmctl :   删除共享内存对象

              函数: int shmctl (int shmid , int cmd , struct shmid_ds *buf);

              参数: shmid :  要操作的共享内存标识符

                  cmd :      IPC_STAT    (获取对象属性)       —————— 实现了  ipcs  -m

                        IPC_SET    (设置对象属性)

                        IPC_RMID    (删除对象) ——————实现了  ipcrm -m

                  buf   :          指定IPC_STAT/IPC_SET  时用以保存/设置属性

              返回值:   成功  :0  ;   出错   :  -1;

                      

              当删除共享内存时,不需要第三个参数,可以设置为NULL

         

     1 include "signal.h"
     2 #include "unistd.h"
     3 #include "stdio.h"
     4 #include "stdlib.h"
     5 #include "sys/types.h"
     6 #include "sys/shm.h"
     7 
     8 int main()
     9 {
    10     int shmid;
    11     char *p;
    12 
    13     shmid = shmget(IPC_PRIVATE,128,0777);
    14 
    15     if(shmid<0)
    16         {
    17            printf("creat share memory failure
    ");
    18            return -1;
    19         }
    20 
    21           printf("craet share meory sucess
    ");    //创建共享内存
    22          system("ipcs -m");
    23 
    24         p = (char *)shmat(shmid,NULL,0);     //映射到用户空间
    25         if(p == NULL)
    26          {
    27             printf("shmat function failure
    ");
    28             return -2;
    29          }
    30             printf("shmat function sucess
    ");
    31 
    32                 //写内容,从键盘输入
    33         fgets(p,128,stdin);
    34 
    35                 //
    36         printf("read : p=%s
    ",p);
    37        return 0;
    38 
    39 }
    40 
    41 
    42 
    43 结果:
    44 craet share meory sucess
    45 
    46 ------------ 共享内存段 --------------
    47 键        shmid      拥有者  权限     字节     连接数  状态      
    48 0x00000000 1179648    xiaozhao   600        524288     2          目标       
    49 0x00000000 393217     xiaozhao   600        524288     2          目标       
    50 0x00000000 425986     xiaozhao   600        524288     2          目标       
    51 0x00000000 688131     xiaozhao   600        524288     2          目标       
    52 0x00000000 720900     xiaozhao   600        16777216   2                       
    53 0x00000000 819205     xiaozhao   600        524288     2          目标       
    54 0x00000000 1081350    xiaozhao   600        524288     2          目标       
    55 0x00000000 950279     xiaozhao   600        67108864   2          目标       
    56 0x00000000 1212424    xiaozhao   600        1048576    2          目标       
    57 0x00000000 1376265    xiaozhao   600        524288     2          目标       
    58 0x00000000 1736714    root       777        128        0                       
    59 
    60 shmat function sucess
    61 1231few
    62 read : p=1231few
    共享内存简单代码
     1 #include "signal.h"
     2 #include "unistd.h"
     3 #include "stdio.h"
     4 #include "stdlib.h"
     5 #include "sys/types.h"
     6 #include "sys/shm.h"
     7 #include "string.h"
     8 
     9 void  fun ( int signum)
    10 {
    11 return ;
    12 
    13 }
    14 int main()
    15 {
    16     int shmid;
    17    int key,pid;
    18    char *p;
    19 
    20     key=ftok("/home/xiaozhao/2.c",'a');  //获取key值 ,在单向通讯中,可以直接使用宏
    21     if(key<0)
    22         {
    23           printf("creat key failure
    ");
    24           return -2;
    25         }
    26           printf("creat key sucess
    ");
    27 
    28 
    29     shmid = shmget(pid,128,IPC_CREAT | 0777);  // 创建共享内存
    30     if(shmid<0)
    31         {
    32            printf("creat share memory failure
    ");
    33            return -1;
    34         }
    35             printf("share meory sucess
    ");
    36 
    37       pid=fork();
    38         if(pid>0)
    39         {
    40           signal(SIGUSR2,fun);
    41           p = (char *)shmat(shmid,NULL,0);  //父进程映射
    42           if(p==NULL)
    43              {
    44                 printf("parent process:shmat function failuer
    ");
    45                 return -3;
    46              }
    47         while(1)
    48         {
    49            printf("parent process start write share memory:
    ");
    50            fgets(p,128,stdin);
    51            kill(pid,SIGUSR1); //child process read data
    52            pause();
    53         }
    54         }
    55 
    56 
    57         if(pid==0)
    58         {
    59           signal(SIGUSR1,fun);
    60         p = (char *)shmat(shmid,NULL,0);
    61         while(1)
    62         {
    63           pause();
    64           printf("share memory data:%s",p);
    65           kill(getppid(),SIGUSR2);
    66         }
    67         }
    68 
    69         shmdt(p);
    70         shmctl(shmid,IPC_RMID,NULL);
    71         system("ipcs -m");
    72 
    73 
    74         return 0;
    75 
    76 }
    77 
    78 
    79 结果:
    80 creat key sucess
    81 share meory sucess
    82 parent process start write share memory:
    83 123
    84 share memory data:123
    85 parent process start write share memory:
    86 123
    87 share memory data:123
    88 parent process start write share memory:
    父子进程单向通信

         fork() 放在 Shmget  之后,可以保证父子进程在同一共享内存中进行。

         六,消息队列

          管道为顺序队列,而消息队列为链式队列

          1,msgget     打开创建消息队列

             头文件: #include <sys/types.h>

                 #include <sys/ipc.h>

                 #include <sys/msg,h>

             函数: int  msgget (key_t key, int flag);

             参数: key  :   和消息队列关联的KEY值

                 flag  :   消息队列的访问权限

             返回值: 成功  :消息队列ID  ;   出错  : -1;

          2,msgctl    删除消息队列

             头文件: #include <sys/types.h>

                 #include <sys/ipc.h>

                 #include <sys/msg,h>

             函数: int msgctl (int msgqid, int cmd,struct msqid_ds *buf);

             参数: msqid   :   消息队列ID

                cmd   :      IPC_STAT  :   读取消息队列的属性,并将其保存在BUF指向的缓存中

                      IPC_SET    :  设置消息队列的属性,这个参数取自BUF

                     IPC_RMID :  从系统中删除消息队列

                buf     :      消息队列缓存区

              返回值:  成功  0    ;  出错  -1;

              当删除消息队列时,不需要第三个参数,可以设置为NULL

      

          3,msgsnd    发送消息

            函数:  int msgsnd (int msqid, const void *msgp,size_t size,int flag);

            参数:  msqid   :    消息队列ID

                 msgp   :     指向消息队的指针。常用消息结构msgbuf 如下:

                                   struct  msgbuf

                                      {

                                       long mtype;        //消息类型

                                       char  mtext[N];   // 消息正文

                                      }

                size    :      发送消息正文的字节数

                flag    :       IPC_NOWAIT        消息没有发送完成函数也会立即返回

                     0                             直到消息发送完成才返回

                返回值:   成功   0  ;   出错    -1;

          4,msgrcv    接收消息

              函数: int  msgrcv (int msgid,   void *msgp ,  size_t size ,   long msgtype ,   int flag);

              参数:   msqid  :    消息队列 ID 

                  msgp :     接收消息的缓冲区

                  size   :      要接收的消息的字节数

                  msgtype:       0     接收消息队列中的第一个消息

                        大于0     接收消息队列中第一个类型为 msgtyp  的消息

                        小于0     接收消息队列中类型值不大于msgtyp 的绝对值且类型又最小的消息

                  flag     :      0       若无消息函数会一直阻塞

                       IPC_NOWAIT       若没有消息,进程会立即返回ENOMSG

              返回值: 成功 :接收到的消息长度    ;    出错    -1;     

            读就是删除,写就是插入。

     1 #include "sys/types.h"
     2 #include "sys/msg.h"
     3 #include "signal.h"
     4 #include "unistd.h"
     5 #include "stdio.h"
     6 #include "stdlib.h"
     7 #include "string.h"
     8 struct msgbuf
     9 {
    10   long type;
    11   char buf[124];
    12 };
    13 
    14 int main()
    15 {
    16    int  msgid;
    17   struct msgbuf sendbuf,readbuf;
    18     msgid =  msgget(IPC_PRIVATE,0777);
    19         if(msgid<0)
    20         {
    21           printf ("creat message queue failure
    ");
    22           return -1;
    23         }
    24           printf("creat message queue sucess , msgid=%d
    ",msgid);
    25 
    26         system("ipcs -q");
    27                 // init sengbuf
    28         sendbuf.type=100;
    29         printf("please input message :
    ");
    30         fgets(sendbuf.buf,124,stdin);
    31         msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.buf),0);
    32 
    33         memset(readbuf.buf,0,124);
    34         msgrcv(msgid,(void *)&readbuf,124,100,0);
    35         printf("read :%s
    ",readbuf.buf);
    36 
    37 //      msgctl(msgid,IPC_RMID,NULL);
    38         system("ipcs -q");
    39 
    40 
    41 
    42 return  0;
    43 
    44 }
    45 
    46 结果:
    47 creat message queue sucess , msgid=98305
    48 
    49 --------- 消息队列 -----------
    50 键        msqid      拥有者  权限     已用字节数 消息      
    51 0x00000000 65536      root       777        0            0           
    52 0x00000000 98305      root       777        0            0           
    53 
    54 please input message :
    55 12321313
    56 read :12321313
    57 
    58 
    59 --------- 消息队列 -----------
    60 键        msqid      拥有者  权限     已用字节数 消息      
    61 0x00000000 65536      root       777        0            0           
    62 0x00000000 98305      root       777        0            0
    消息队列简单读取
      1 write:
      2 #include "sys/types.h"
      3 #include "sys/msg.h"
      4 #include "signal.h"
      5 #include "unistd.h"
      6 #include "stdio.h"
      7 #include "stdlib.h"
      8 #include "string.h"
      9 struct msgbuf
     10 {
     11   long type;
     12   char buf[124];
     13 };
     14 
     15 int main()
     16 {
     17    int  msgid;
     18    int key;
     19          struct msgbuf sendbuf;
     20          key=ftok("/home/xiaozhao/b.c",'a');
     21     if(key<0)
     22     { printf(" creat key failure
    "); 
     23         return -2;}
     24          printf("creat key sucess
    ");    
     25         msgid =  msgget(key, IPC_CREAT | 0777);
     26     if(msgid<0)
     27     {
     28           printf ("creat message queue failure
    ");
     29       return -1;    
     30     }
     31           printf("creat message queue sucess , msgid=%d
    ",msgid);
     32 
     33     system("ipcs -q");
     34         // init sengbuf    
     35     sendbuf.type=100;
     36 while(1)
     37 {
     38     printf("please input message :
    ");
     39     fgets(sendbuf.buf,124,stdin);
     40     msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.buf),0);
     41 
     42 //      memset(readbuf.buf,0,124);
     43 //    msgrcv(msgid,(void *)&readbuf,124,100,0);
     44 //    printf("read :%s
    ",readbuf.buf);
     45 }
     46     msgctl(msgid,IPC_RMID,NULL);
     47     system("ipcs -q");
     48         return  0;
     49 }
     50 
     51 
     52 
     53 
     54 read:
     55 #include "sys/types.h"
     56 #include "sys/msg.h"
     57 #include "signal.h"
     58 #include "unistd.h"
     59 #include "stdio.h"
     60 #include "stdlib.h"
     61 #include "string.h"
     62 struct msgbuf
     63 {
     64   long type;
     65   char buf[124];
     66 };
     67 
     68 int main()
     69 {
     70    int  msgid;
     71    int key;
     72          struct msgbuf readbuf;
     73          key=ftok("/home/xiaozhao/b.c",'a');
     74     if(key<0)
     75     { printf(" creat key failure
    "); 
     76         return -2;}
     77 printf("creat key sucess
    ");    
     78         msgid =  msgget(key, IPC_CREAT | 0777);
     79     if(msgid<0)
     80     {
     81           printf ("creat message queue failure
    ");
     82       return -1;    
     83     }
     84           printf("creat message queue sucess , msgid=%d
    ",msgid);
     85 
     86     system("ipcs -q");
     87         // init sengbuf    
     88 //    sendbuf.type=100;
     89 while(1)
     90 {
     91 //    printf("please input message :
    ");
     92 //    fgets(sendbuf.buf,124,stdin);
     93 //    msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.buf),0);
     94 
     95         memset(readbuf.buf,0,124);
     96     msgrcv(msgid,(void *)&readbuf,124,100,0);
     97     printf("read :%s
    ",readbuf.buf);
     98 }
     99     msgctl(msgid,IPC_RMID,NULL);
    100     system("ipcs -q");
    101         return  0;
    102 }
    103  
    消息队列单向通信

            消息队列双向通信必须保证收发数据类型不同,用父子进程可以实现

       七,信号灯 

            信号量的集合

        1,semget                 创建信号灯

                头文件:#include <sys/types.h>

                    #include <sys/ipc.h>

                    #include <sys.sem.h>

                函数: int semget (key_t key ,int nsems ,int semfig);

                参数: key :       和信号灯集关联的key 值

                  nsems:        信号灯集合包含的信号灯数目

                  semfig :     信号灯集的访问权限

                返回值: 成功 :  信号灯集ID    出错  :   -1

        2, semctl                    删除信号灯

                头文件: #include  <sys/types.h>

                    #inlcude <sys/ipc.h>

                    #include <sys/sem.h>

                函数:   int  semctl ( int semid , int semnum , int cmd ,...union semun arg);

                参数:   semid   :    信号灯集ID

                      semnum   :    要修改的信号灯编号

                    cmd     :      GETVAL   :    获取信号灯的值

                         SETVAL    :  设置信号灯的值

                         IPC_RMID :  从系统中删除信号灯集合

                     (删除时) 第四个参数可以NULL,也可以不写。 

                 返回值 ;   成功  :0    ; 出错  -1

            

              设置信号灯时用到第四个参数(联合体)

              union  semun

                {

                  int val;

                    // SETVAL  :   设置信号灯的值

                  struct semid_ds *buf;

                    // IPC_STAT   (获取对象属性)

                    //IPC_SET        (设置对象属性)

                  unsigned short  *array ;    /* Array for GETALL,SETALL */

                  struct seminfo   *_buf   ;   /*Buffer for IPC_INFO (Linux-specific) */

                };

        3,semop                信号灯P操作

                头文件 : #include  <sys/types.h>

                    #inlcude <sys/ipc.h>

                    #include <sys/sem.h>

                函数 ;   int  semop  (  int semid ,struct sembuf  *opsptr ,  size_t nops);

                参数 :   semid   :   信号灯集ID

                   struct sembuf {

                     short  sem_num;    //要操作的信号灯的编号

                     short  sem_op ;      //   0  :  等待 , 直到信号灯的值变成0    

                               1  :  释放资源,V操作

                                -1   :  分配资源,P操作

                       short   sem_fig ;     //    0(阻塞),IPC_NOWAIT(非阻塞), SEM_UNDO()

                      }

      

  • 相关阅读:
    索引使用及注意事项
    Explain详解与索引
    JVM常量池了解
    认识Mysql索引
    JVM调优工具及了解
    JVM垃圾收集器
    JVM垃圾回收相关算法
    JVM字节码文件结构剖析
    JVM对象创建与内存分配机制
    JVM内存参数设置
  • 原文地址:https://www.cnblogs.com/chu-yi/p/9817495.html
Copyright © 2020-2023  润新知