Linux 进程间通信

2018-10-24 08:41:17来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

 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\n");
     return -1;
   }
     printf("creat process success ,fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);

     write(fd[1],write_buf,sizeof(write_buf));
     read(fd[0],read_buf,128);
     printf("read:%s\n",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\n",i);
10     return;
11 
12 }
13 int main()
14 {
15      int i;
16      i=0;
17      signal(14,myfun);
18      printf("alarm before\n");
19      alarm(4);
20      printf("alarm after\n");
21 
22      while(i<10)
23       {
24          i++;
25          sleep(1);
26         printf("main,i=%d\n",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\n");
19            return -1;
20         }
21 
22           printf("craet share meory sucess\n");    //创建共享内存
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\n");
18            return -1;
19         }
20 
21           printf("craet share meory sucess\n");    //创建共享内存
22          system("ipcs -m");
23 
24         p = (char *)shmat(shmid,NULL,0);     //映射到用户空间
25         if(p == NULL)
26          {
27             printf("shmat function failure\n");
28             return -2;
29          }
30             printf("shmat function sucess\n");
31 
32                 //写内容,从键盘输入
33         fgets(p,128,stdin);
34 
35                 //
36         printf("read : p=%s\n",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\n");
24           return -2;
25         }
26           printf("creat key sucess\n");
27 
28 
29     shmid = shmget(pid,128,IPC_CREAT | 0777);  // 创建共享内存
30     if(shmid<0)
31         {
32            printf("creat share memory failure\n");
33            return -1;
34         }
35             printf("share meory sucess\n");
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\n");
45                 return -3;
46              }
47         while(1)
48         {
49            printf("parent process start write share memory:\n");
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\n");
22           return -1;
23         }
24           printf("creat message queue sucess , msgid=%d\n",msgid);
25 
26         system("ipcs -q");
27                 // init sengbuf
28         sendbuf.type=100;
29         printf("please input message :\n");
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\n",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\n"); 
 23         return -2;}
 24          printf("creat key sucess\n");    
 25         msgid =  msgget(key, IPC_CREAT | 0777);
 26     if(msgid<0)
 27     {
 28           printf ("creat message queue failure\n");
 29       return -1;    
 30     }
 31           printf("creat message queue sucess , msgid=%d\n",msgid);
 32 
 33     system("ipcs -q");
 34         // init sengbuf    
 35     sendbuf.type=100;
 36 while(1)
 37 {
 38     printf("please input message :\n");
 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\n",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\n"); 
 76         return -2;}
 77 printf("creat key sucess\n");    
 78         msgid =  msgget(key, IPC_CREAT | 0777);
 79     if(msgid<0)
 80     {
 81           printf ("creat message queue failure\n");
 82       return -1;    
 83     }
 84           printf("creat message queue sucess , msgid=%d\n",msgid);
 85 
 86     system("ipcs -q");
 87         // init sengbuf    
 88 //    sendbuf.type=100;
 89 while(1)
 90 {
 91 //    printf("please input message :\n");
 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\n",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()

                  }

  

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Linux中FTP的一点理解

下一篇:Linux 获取帮助