Linux环境编程进程间通信机制理解
一、Linux系统调用主要函数二、创建进程 1、创建子进程系统调用fork() 2、验证fork()创建子进程效果 3、系统调用fork()与挂起系统调用wait() 三、模拟进程管道通信 四、pipe()下生产者与消费者问题 总结 一、Linux系统调用主要函数首先,认识一下Linux下系统调用的主要函数,为后面进程与通信等做好铺垫。 以下是 Linux 系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的函数。
二、创建进程接下来这部分相当于程序设计,通过系统调用创建进程,然后根据执行顺序进行判断,理解主进程和子进程的关系。 1、创建子进程系统调用fork()#include <unistd.h> #include <sys/types.h> #include<stdio.h> int main () { pid_t pid; /* pid_t 是 short 类型 */ pid=fork(); if (pid < 0) printf("error in fork!"); else if (pid == i am the child process,my process id is %dn,getpid()); else printf(i am the parent process,1)">return ; } 这个程序很好理解: fork()返回值0,进入子进程,返回值1,进入父进程,-1则是创建失败。 主要理解父子进程执行顺序是否与程序结构(判断语句前后)有关,所以再次进行以下测试,修改了判断语句顺序: #include <unistd.h>if (pid > ; } 根据实验结果如图,对比之后发现运行结果相同,说明父子进程运行顺序与判断语句次序无关,始终是父进程优先执行。 2、验证fork()创建子进程效果首先,我们再次对以上程序进行修改,第一次,测试打印语句放于fork()之前,观察结果: #include <unistd.h> printf(see the print timesn); pid=; } 第二次,将打印测试放在fork()之后,结果: 由此可见得,在fork()创建子进程之后,有两个进程进行执行操作,所以执行了两次测试打印。 3、系统调用fork()与挂起系统调用wait()实现代码如下: #include <unistd.h> #include<sys/wait.h> #include<stdio.h> #include<stdlib.h> i,st; pid_t pid1,pid2; int sub_proc1( id); int sub_proc2( main() { printf(nnnif ((pid1 = fork()) == ) { printf(The first child process id is %dn1);} printf(i am the parent process id=%d nif ((pid2 = fork()) == The second child process id is %dn2st); i = wait(&st); printf(n all finished!!!!!!!!!!!!!!!!!!n); exit(; } id) { printf(sub_proc%d is running !nsub_proc%d finish n 解析:初始化创建了两个主进程,系统调用wait()更直观看出,程序先执行第一个主进程,再执行其子进程;然后执行第二个主进程,再执行其子进程。按照这个执行顺序,感知父子进程直接的关系,以及两个进程之间的执行顺序。证明结果: 三、模拟进程管道通信我们知道,管道是进程之间的通信方法之一,?接下来通过进程的创建、管道的设置,实现进程间通过管道进行通信,然后认识在?Linux下进程间通过管道通信的编程。 原理:pipe() 把 p[ ] 与两个文件描述符紧密联系起来: 使用到系统调用函数pipe() ?和 fork() #include <stdio.h> #include<stdlib.h> #include <unistd.h> #include <sys/wait.h> #define MSGSIZE 16 int pipe(int p[]); char *msg1=hello,world #1; char *msg2=char *msg3= main() { char inbuf[MSGSIZE]; ],i,pid; if (pipe(p) < 0) 打开管道 { perror(pipe error!"); 无法打开一个管道错 exit(); } if ( (pid = fork()) < ) { perror(fork); exit( 父进程 { close(p[0]); 关闭读端(连接) write(p[int *)); } 子进程 1]); 关闭写端 */ for (i=0; i < 3; i++) { read(p[%sn; } 结果实现不同进行之间的通信,通过不同管道进行读写操作: ? 进程管道通信需要注意下面几个问题: (1)关闭了一个方向 (2)管道的大小(Size) (3)写问题: write() 将被挂起(阻塞),如果管道中无法存放正文(容量不够),可能在写的过程中发生阻塞; 如果向一个没有读连接的管道写,将返回 -1,且 errno 被置成 EPIPE。errno 是一个全局变量。 (4)读问题: read() 将被阻塞,如果管道空,且有一个 写连接开放,read() 将返回 0 。 四、pipe()下生产者与消费者问题经典同步互斥问题,现在初始化有一个生产者,两个消费者,只有生产者有生产物资后,消费者才能使用,否则进入等待。 #include<sys/types.h> #include<sys/file.h> #include<string.h> #include<unistd.h> #include <stdio.h> char r_buf[4]; //读缓冲 char w_buf[写缓冲 int pipe_fd[]; pid_t pid1,1)">int producer(int consumer(int i,pid,status; status 用来表示进程退出的状态 */ if(pipe(pipe_fd)<) { printf(pipe create error n); exit(- { printf(pipe is created successfully!n); if((pid1=fork())==) producer(if((pid2=fork())==) consumer(); } close(pipe_fd[0]);否则会有读者或者写者永远等待 close(pipe_fd[]); for(i=0;i<2;i++) pid=wait(&status); 等待子进程完成(取返回状态信息),主进程后 面未利用子进程的什么结果,直接在子进程完成后退出 exit(); } id) { i; printf(producer %d is running!n1;i<10;i++) { sleep(3); strcpy(w_buf,aaa if(write(pipe_fd[1],w_buf,4)==-) printf(write to pipe errorn); } close(pipe_fd[]); printf(producer %d is over!n id) { close(pipe_fd[consumer %d is running!nbbb while(); strcpy(r_buf,1)">eee if(read(pipe_fd[0],r_buf,1)">4)==) break; printf(consumer %d get %s,while the w_buf is %snconsumer %d is over!nView Code 进程执行如下: 总结学习之后的一篇总结,玩转Linux编程,更加深刻地去体验其中的原理,掌握基本的知识和操作。这篇记录总结学习,可以认识到程序与进程的区别,还有进程间通信机制,进程的执行顺序和关系。Linux系统调用函数的认识和使用更进一步掌握相关Linux知识。 另外,进程间的通信机制还有其他方法,进程信号中断通信内容,互斥同步问题,银行家算法等期待后续的学习总结记录,学习分享记录每一步,希望也能够帮助到有需要的朋友,大佬也多多指正! 我的CSDN博客:https://blog.csdn.net/Charzous/article/details/108287075 我的博客园:https://www.cnblogs.com/chenzhenhong/p/13580356.html 版权声明:本文为博主原创文章,遵循?CC 4.0 BY-SA?版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/Charzous/article/details/108287075 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Linux Software Raid在本月的第一个星期日运行checkarray?
- 接口文档管理神器RAP2安装和部署
- linux – 这个bash脚本有多危险?
- linux – 从文本表示生成UML图
- LINUX实操:CentOS 7 通过nmcli team实现多网卡绑定
- linux – /etc/cron.d和/ var / spool / cron有什么区别?
- linux – 以编程方式向用户的crontab添加条目
- linux – 在没有GNOME的服务器上安装ssconvert(gnumeric的一
- 从Linux上的汇编代码调用SDL / OpenGL
- linux – UNIX(AIX)脚本,仅使用awk或其他文件处理实用程序处