LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2056|回复: 4

让进程之间的通信更加灵活与高效,Linux的信号也可以传参数

[复制链接]
发表于 2007-5-21 15:03:35 | 显示全部楼层 |阅读模式
代码如下,centOS 4.4编译运行通过
  1. #include <unistd.h>
  2. #include <signal.h>
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. #define SIG_STOP_CHILD SIGRTMIN+1
  7. int main()
  8. {
  9. pid_t pid;
  10. sigset_t newmask;
  11. int rcvd_sig;
  12. siginfo_t info;
  13.     if ((pid = fork()) == 0) {       /*Child*/
  14.         sigemptyset(&newmask);
  15.         sigaddset(&newmask, SIG_STOP_CHILD);
  16.         sigprocmask(SIG_BLOCK, &newmask, NULL);
  17.         while (1) {
  18.             rcvd_sig = sigwaitinfo(&newmask, &info);
  19.             if (rcvd_sig == -1) {
  20.                perror("sigusr: sigwaitinfo");
  21.                _exit(1);
  22.             }
  23.             else {
  24.                  printf("Signal %d, value %d  received from parent\n",
  25.                      rcvd_sig, info.si_value.sival_int);
  26.                _exit(0);
  27.             }
  28.         }
  29.     }
  30.     else {                           /* Parent */
  31.         sigval_t sval;
  32.         sval.sival_int = 1;
  33.         int stat;
  34.         sleep(1);
  35.         sigqueue(pid, SIG_STOP_CHILD, sval);
  36.         pid = wait(&stat);
  37.         printf("Child exit status = %d\n", WEXITSTATUS(stat));
  38.         _exit(0);
  39.     }
  40. }
复制代码
 楼主| 发表于 2007-5-21 21:54:06 | 显示全部楼层
因为只能传个int值给子进程,似乎还不够好,下面一个程序用共享内存的机制,实现传更多的数据给子进程。debian sid 编译运行通过。
  1. #include <unistd.h>
  2. #include <signal.h>
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. #include <sys/ipc.h>
  7. #include <sys/shm.h>
  8. #include <stdlib.h>
  9. #include <fcntl.h>
  10. /* ERROR PRINT*/
  11. #define STD_FUNC "Standard function "
  12. #define SIG_STOP_CHILD SIGRTMIN+1
  13. #define BUFSIZE 4096
  14. int main()
  15. {
  16.         pid_t pid;
  17.         sigset_t newmask;
  18.         int rcvd_sig;
  19.         siginfo_t info;
  20.         char tmpnm[L_tmpnam] = "";
  21.         if( NULL == tmpnam(tmpnm)) {
  22.                 perror( STD_FUNC "tmpnamm failed:");
  23.                 exit(-1);
  24.         }
  25.         int fd = open(tmpnm, O_CREAT | O_EXCL);
  26.         if( -1 == fd) {
  27.                 perror( STD_FUNC "open failed:");
  28.                 exit(-1);
  29.         }
  30.         key_t shk = ftok(tmpnm, 'X');
  31.         if( -1 == shk) {
  32.                 perror( STD_FUNC "ftok failed:");
  33.                 exit(-1);
  34.         }
  35.         int shm_id = shmget(shk, BUFSIZE+1, IPC_CREAT | IPC_EXCL);
  36.         if ( -1 == shm_id) {
  37.                 perror( STD_FUNC "shmget failed:");
  38.                 exit( -1);
  39.         }
  40.        
  41.     if ((pid = fork()) == 0) {       /*Child*/
  42.         sigemptyset(&newmask);
  43.         sigaddset(&newmask, SIG_STOP_CHILD);
  44.         sigprocmask(SIG_BLOCK, &newmask, NULL);
  45.         while (1) {
  46.             rcvd_sig = sigwaitinfo(&newmask, &info);
  47.             if (rcvd_sig == -1) {
  48.                perror("sigusr: sigwaitinfo");
  49.                _exit(1);
  50.             }
  51.             else {
  52.                                 char * shm_buf = (char *)shmat(shm_id, NULL, 0);
  53.                                 if( (char *)-1 == shm_buf) {
  54.                                         perror( STD_FUNC"shmat failed:");
  55.                                         exit(-1);
  56.                                 }               
  57.                                 printf("Signal %d, value %d  string "%s" received from parent\n",
  58.                      rcvd_sig, info.si_value.sival_ptr, shm_buf);
  59.                                 shmdt( shm_buf);
  60.                _exit(0);
  61.             }
  62.         }
  63.     }
  64.     else {                           /* Parent */
  65.         sigval_t sval;
  66.         sval.sival_int = 1;
  67.                 char * shm_buf = (char *)shmat(shm_id, NULL, 0);
  68.                 if( (char *)-1 == shm_buf) {
  69.                         perror( STD_FUNC "shmat failed:");
  70.                         exit(-1);
  71.                 }
  72.                 sprintf( shm_buf, "%s", "Hello World!");
  73.         int stat;
  74.         sleep(1);
  75.         sigqueue(pid, SIG_STOP_CHILD, sval);
  76.         pid = wait(&stat);
  77.         printf("Child exit status = %d\n", WEXITSTATUS(stat));
  78.                 shmdt( shm_buf);
  79.                 shmctl(shm_id, IPC_RMID, NULL);
  80.                 close(fd);
  81.         _exit(0);
  82.     }
  83. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-5-22 12:08:45 | 显示全部楼层
realtang 兄的文章篇篇都是精品, 偶像啊!
回复 支持 反对

使用道具 举报

发表于 2007-5-22 21:08:24 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-5-23 10:32:39 | 显示全部楼层
多谢rickxbx兄补充。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表