标签:实现 技术分享 led printf 进程 进程创建 src get shmat
/* * 题目: * 编写程序,要去实现如下功能: 父进程创建子进程1和子进程2、子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2; 子进程2接受可靠信号的值,并发送给父进程,父进程把接受的值进行打印。 提示:用sigqueue和sigaction实现 * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/wait.h> #include <signal.h> #include <sys/shm.h> /* 分析: * 子进程2将pid存入共享内存区,子进程1从共享内存区中读取子进程2的pid,向子进程2发送带数据的信号 * */ //子进程2信号安装回调函数 void handler(int sign, siginfo_t * info, void *p) { if (sign == SIGRTMIN) { printf("子进程2接收到数据%d\n",info->si_value.sival_int); //向父进程发送信号 if (sigqueue(getppid(), SIGRTMIN, info->si_value) != 0) { perror("sigqueue() err"); return; } //退出子进程2 printf("子进程2 quit\n"); exit(0); } } //父进程信号安装回调函数 void handlerf(int sign, siginfo_t * info, void *p) { if (sign == SIGRTMIN) { //打印信号值 printf("父进程接收的值是%d\n", info->si_value.sival_int); } } int main(int arg, char *args[]) { //创建共享内存区 int shmid = shmget(IPC_PRIVATE, sizeof(int), 0666); if (shmid == -1) { printf("shmget() failed !\n"); return -1; } pid_t pid = 0; pid = fork(); if (pid == -1) { perror("fork() err"); return -1; } if (pid == 0) { //子进程1 printf("子进程1的pid=%d\n", getpid()); int *pid2 = NULL; //子进程1附加到共享内存区 pid2 = (int *) shmat(shmid, 0, 0); if ((int) pid2 == -1) { perror("shmat() err"); return -1; } //等待进程2向共享内存区写入数据 while (*pid2 == 0) { //等待共享内存区中有数据 sleep(1); } //向进程2发送可靠信号 union sigval v1; v1.sival_int = getpid() * 2; if (sigqueue(*pid2, SIGRTMIN, v1) != 0) { perror("sigqueue() err"); return -1; } //发送完信号后,进程1退出 printf("子进程1 exit\n"); exit(0); } pid = fork(); if (pid == -1) { perror("fork() err"); return -1; } if (pid == 0) { //子进程2 printf("子进程2的pid=%d\n", getpid()); //安装信号SIGRTMIN struct sigaction act; act.sa_sigaction = handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; if (sigaction(SIGRTMIN, &act, NULL) != 0) { printf("sigaction() failed !\n"); return -1; } int *mypid = NULL; //子进程2附加到共享内存区 mypid = (int *) shmat(shmid, 0, 0); if ((int) mypid == -1) { perror("shmat() err"); return -1; } //将子进程2的pid放到共享内存区,操作私有共享内存区,映射到系统共享内存区 *mypid = getpid(); //等待子进程1向自己发送信号 while (1) { printf("子进程2 sleep\n"); sleep(1); } } //父进程 //安装信号SIGRTMIN struct sigaction act; act.sa_sigaction = handlerf; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; if (sigaction(SIGRTMIN, &act, NULL) != 0) { printf("sigaction() failed !\n"); return -1; } int ret=0; //等待子进程 while(1) { ret=wait(NULL); printf("子进程pid=%d\n",ret); if(ret==-1) { if(errno==EINTR) { continue; } break; } } //释放共享内存区 if (shmctl(shmid, IPC_RMID, NULL) != 0) { printf("shmctl() failed!\n"); } printf("game is over !\n"); return 0; } /* * 出错总结:gdb报错:shmat() err: Invalid argument,意思是shmat()参数不正确 * 经过半天分析,发现我在父进程中没有wait子进程,直接调用了shmctl()函数,把共享内存给释放了,所以报错 * */
Linux Linux程序练习十五(进程间的通信共享内存版)
标签:实现 技术分享 led printf 进程 进程创建 src get shmat
原文地址:http://www.cnblogs.com/zhanggaofeng/p/6123957.html