1、信号的局限性
进程虽然高度独立和封闭,但进程依然有通信的需要。
信号——中断,信号能够实现一定程度的进程间通信,但它是高度抽象,所表达的含义是告诉某一个进程什么事情发生了。信号却不能够传递复杂的、有效的、具体的数据,这就是信号的局限性。
就需要其他的手段来构建进程间复杂数据的传递。
2、基于文件的进程间通信
早期的系统中,为了能够让进程之间方便的共享数据,最容易想到的解决方案就是,使用磁盘上的文件系统(因为文件系统对于所有进程都是公开且共享的)。
进行文件间通信代码:
#include<stdio.h> #include<unistd.h> #include<string.h> #include<fcntl.h> #include<stdlib.h> #include<sys/types.h> int main(void){ pid_t pid; int fd; char buf[80]; pid = fork(); if(pid == 0){ fd = open("./tmp", O_CREAT | O_WRONLY, 0755); if(fd < 0){ perror(""); exit(-1); } sprintf(buf, "I am child, This msg is pid=%d\n", getpid()); write(fd, buf, strlen(buf)); close(fd); sleep(5); }else if(pid > 0){ sleep(1); fd = open("./tmp", O_APPEND | O_RDONLY); if(fd < 0){ perror(""); exit(-1); } read(fd, buf, sizeof(buf)); printf("I am father, I have recv a msg : [%s]\n", buf); close(fd); }else{ perror(""); } return 0; }
运行结果
3、文件间的往来通信
为了能够实现两个进程通过文件进行有序的数据交流,还得借助于信号的处理机制。
(1)、通过pause()等待对方发起一个信号,已确认可以开始执行下一次读/写操作;
(2)、通过kill()方法向对方发出明确的信号:可以开始下一步执行(读、写);
文件通信,代码如下:
#include<stdio.h> #include<unistd.h> #include<string.h> #include<fcntl.h> #include<stdlib.h> #include<signal.h> #include<sys/types.h> void catch_SIGUSR1(int sig){} int main(void){ pid_t pid; int fd; char buf[80]; int i; signal(SIGUSR1, catch_SIGUSR1); pid = fork(); if(pid == 0){ fd = open("./tmp", O_CREAT | O_WRONLY, 0755); if(fd < 0){ perror(""); exit(-1); } for(i = 0; i < 5; i++){ sprintf(buf, "I am child, This msg is pid=%d i=%d\n", getpid(), i); write(fd, buf, strlen(buf)); sleep(1); //速度太快,写完的休眠1秒,有时间让父进程读取数据。 kill(getppid(),SIGUSR1); pause(); } close(fd); sleep(5); }else if(pid > 0){ pause(); fd = open("./tmp", O_APPEND | O_RDONLY); if(fd < 0){ perror(""); exit(-1); } for(i = 0; i < 5; i++){ read(fd, buf, sizeof(buf)); printf("I am father, I have recv a msg : [%s]\n", buf); sleep(1); //速度太快,读完的休眠1秒,有时间让子进程写入数据。 kill(pid, SIGUSR1); pause(); } close(fd); }else{ perror(""); } return 0; }
运行结果
这样就利用文件达到了父子进程之间的通信了。
由以上的代码可以看出:直接通过文件的方式进行的进程间的通信的编程控制是非常复杂的,就需要一种更加简洁的处理方案。
时间: 2024-10-15 02:38:02