IPC进程间的通信(下篇)共享内存和信号量

共享内存

共享内存的简单调用一般是

  1. 键值的创建
  2. shmget函数创建共享内存空间
  3. shmat函数获取第一个可用共享内存空间的地址
  4. shmdt函数进行分离(对共享存储段操作结束时的步骤,并不是从系统中删除共享内存和结构)
  5. shmctl函数进行删除共享存储空间
    我们就可以根据这五个步骤简单的编写一个写入的代码和读取的代码。

写入的代码:

  1 #include <sys/ipc.h>
  2 #include <sys/shm.h>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <string.h>
  6 int main()
  7 {
  8         int shmId;
  9         char *shmadd;
 10         key_t key;
 11         key = ftok(".",1);
 12         shmId = shmget(key,1024*4,IPC_CREAT|0600);
 13         if(shmId == -1){
 14                 printf("failed\n");
 15                 exit(-1);
 16         }
 17         shmadd = shmat(shmId,0,0);
 18         printf("shmat ok\n");
 19         strcpy(shmadd,"this is test");
 20         sleep(5);
 21         shmdt(shmadd);
 22         shmctl(shmId,IPC_RMID,0);
 23         return 0;
 24 }

读取的代码

  1 #include <sys/ipc.h>
  2 #include <sys/shm.h>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <string.h>
  6 int main()
  7 {
  8         int shmId;
  9         char *shmadd;
 10         key_t key;
 11         key = ftok(".",1);
 12         shmId = shmget(key,1024*4,0);
 13         if(shmId == -1){
 14                 printf("failed\n");
 15                 exit(-1);
 16         }
 17         shmadd = shmat(shmId,0,0);
 18         printf("shmat ok\n");
 19         printf("msg:%s\n",shmadd);
 20         shmdt(shmadd);
 21         shmctl(shmId,IPC_RMID,0);
 22         return 0;
 23 }

在写入的代码里,我们要先创建一个键值 key_t key,然后使用shmget函数来创建共享内存,权限是可读可写。
然后获取共享内存空间第一个地址,shmat函数来实现,我们要先定义一个字符型的指针,shmat的返回值给到这个指针上。
在用strcpy函数,把内容的地址传到指针上,这样就完成共享内存的写入了。
后面就是分离和关闭共享内存了。

在读取的代码里,就更简单了,与写入代码不用的是,我们不需要strcpy函数,我们只要打开共享内存,获取共享内存第一个地址,就能直接读取出来,代码里是直接打印出来。

信号

我们平常在进程运行的时候,有时候会退不出来,像如果有一个while(1)函数,在主函数里,这个程序就会一直循环,这个时候我们按下ctrl+c就能终止运行。这个就是信号的使用,可以使用signal函数,就可以知道这个函数的值,并且在收到信号的时候就会打印出来。我们也使用kill -9 xxxxx,来杀死进程,这个信号是不可忽略的。
我们可以利用信号来传递信息:
接收端的代码:

  1 #include <stdio.h>
  2 #include <signal.h>
  3 
  4 //       int sigaction(int signum, const struct sigaction *act,
  5   //                   struct sigaction *oldact);
  6 void handler(int signum,siginfo_t *info,void *context)
  7 {
  8                 printf("get signum = %d\n",signum);
  9                 if(context != NULL){
 10                         printf("get data = %d\n",info->si_int);
 11                         printf("info pid = %d\n",info->si_pid);
 12                 }
 13 }
 14 
 15 int main ()
 16 {
 17         struct sigaction act;
 18         act.sa_sigaction = handler;
 19         act.sa_flags = SA_SIGINFO;
 20         sigaction(SIGUSR1,&act,NULL);
 21         printf("pid = %d\n",getpid());
 22         while(1);
 23         return 0;
 24 }
~          

写入端的代码:

  1 #include <signal.h>
  2 #include <stdio.h>
  3       // int sigqueue(pid_t pid, int sig, const union sigval value);
  4 int main(int argc,char **argv)
  5 {
  6         int pid;
  7         int signum;
  8         signum = atoi(argv[1]);
  9         pid = atoi(argv[2]);
 10         union sigval value;//这个是联合体
 11         value.sival_int = 100;
 12         sigqueue(pid,signum,value);
 13         printf("done\n");
 14         printf("pid = %d",getpid());
 15         return 0;
 16 }
~      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值