自己做的网站背景怎么设置,移动宽带到期续费流程,大学生网页制作成品模板,传奇页游什么好玩from#xff1a;https://blog.csdn.net/skyroben/article/details/715133851.进程间通信每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到#xff0c;所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内…fromhttps://blog.csdn.net/skyroben/article/details/715133851.进程间通信 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。
12不同进程间的通信本质进程之间可以看到一份公共资源而提供这份资源的形式或者提供者不同造成了通信方式不同而 pipe就是提供这份公共资源的形式的一种。2.匿名管道2.1管道的创建 管道是由调用pipe函数来创建
12#include unistd.h
int pipe (int fd[2]);//返回:成功返回0出错返回-1 123 fd参数返回两个文件描述符,fd[0]指向管道的读端,fd[1]指向管道的写端。fd[1]的输出是fd[0]的输入。
122.2管道如何实现进程间的通信1父进程创建管道得到两个⽂件描述符指向管道的两端2父进程fork出子进程⼦进程也有两个⽂件描述符指向同⼀管道。3父进程关闭fd[0],子进程关闭fd[1]即⽗进程关闭管道读端,⼦进程关闭管道写端因为管道只支持单向通信。⽗进程可以往管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。 2.3如和用代码实现管道通信[cpp] view plain copy#include stdio.h #include unistd.h #include string.h #include errno.h int main() { int fd[2]; int ret pipe(fd); if (ret -1) { perror(”pipe error\n”); return 1; } pid_t id fork(); if (id 0) {//child int i 0; close(fd[0]); char *child “I am child!”; while (i5) { write(fd[1], child, strlen(child) 1); sleep(2); i; } } else if (id0) {//father close(fd[1]); char msg[100]; int j 0; while (j5) { memset(msg,’\0’,sizeof(msg)); ssize_t s read(fd[0], msg, sizeof(msg)); if (s0) { msg[s - 1] ’\0’; } printf(”%s\n”, msg); j; } } else {//error perror(”fork error\n”); return 2; } return 0; } 运行结果每隔2秒打印一次I am child! 并且打印了五次。
122.4管道读取数据的四种的情况1读端不读写端一直写 2写端不写但是读端一直读 3读端一直读且fd[0]保持打开而写端写了一部分数据不写了并且关闭fd[1]。 如果一个管道读端一直在读数据而管道写端的引⽤计数⼤于0决定管道是否会堵塞引用计数大于0只读不写会导致管道堵塞。4读端读了一部分数据不读了且关闭fd[0]写端一直在写且f[1]还保持打开状态。[cpp] view plain copy#include stdio.h #include unistd.h #include string.h #include errno.h int main() { int fd[2]; int ret pipe(fd); if (ret -1) { perror(”pipe error\n”); return 1; } pid_t id fork(); if (id 0) {//child int i 0; close(fd[0]); char *child “I am child!”; while (i10) { write(fd[1], child, strlen(child) 1); sleep(2); i; } } else if (id0) {//father close(fd[1]); char msg[100]; int status 0; int j 0; while (j5) { memset(msg, ’\0’, sizeof(msg)); ssize_t s read(fd[0], msg, sizeof(msg)); if (s0) { msg[s - 1] ’\0’; } printf(”%s %d\n”, msg, j); j; } //写方还在继续,而读方已经关闭它的读端 close(fd[0]); pid_t ret waitpid(id, status, 0); printf(”exitsingle(%d),exit(%d)\n”, status 0xff, (status 8) 0xff); //低八位存放该子进程退出时是否收到信号 //此低八位子进程正常退出时,退出码是多少 } else {//error perror(”fork error\n”); return 2; } return 0; } 运行结果使用kill -l 查看13号信号可以知道13号信号代表SIGPIPE。总结 如果一个管道的写端一直在写而读端的引⽤计数是否⼤于0决定管道是否会堵塞引用计数大于0只写不读再次调用write会导致管道堵塞 如果一个管道的读端一直在读而写端的引⽤计数是否⼤于0决定管道是否会堵塞引用计数大于0只读不写再次调用read会导致管道堵塞 而当他们的引用计数等于0时只写不读会导致写端的进程收到一个SIGPIPE信号导致进程终止只写不读会导致read返回0,就像读到⽂件末尾⼀样。2.5管道特点1.管道只允许具有血缘关系的进程间通信如父子进程间的通信。2.管道只允许单向通信。3.管道内部保证同步机制从而保证访问数据的一致性。4.面向字节流5.管道随进程进程在管道在进程消失管道对应的端口也关闭两个进程都消失管道也消失。
123456789102.6管道容量大小测试管道容量大小只需要将写端一直写读端不读且不关闭fd[0],即可。 测试代码#include stdio.h
#include unistd.h
#include string.h
#include errno.h
int main()
{int fd[2];int ret pipe(fd);if (ret -1){perror(pipe error\n);return 1;}pid_t id fork();if (id 0){//childint i 0;close(fd[0]);char *child I am child!;while (i){write(fd[1], child, strlen(child) 1);printf(pipe capacity: %d\n, i*(strlen(child) 1));}close(fd[1]);}else if (id0){//fatherclose(fd[1]);waitpid(id, NULL, 0);}else{//errorperror(fork error\n);return 2;}return 0;
}1234567891011121314151617181920212223242526272829303132333435363738可以看到写到65520之后管道堵塞了而65520即为64K大小即为管道的容量。 进程间通信方式———信号量Semaphore http://blog.csdn.net/skyroben/article/details/72513985进程间通信方式———消息队列 http://blog.csdn.net/skyroben/article/details/72520501进程间通信方式——共享内存 http://blog.csdn.net/skyroben/article/details/72625028版权声明本文为博主原创文章转载请注明出处。 https://blog.csdn.net/skyroben/article/details/71513385