没有网站如何做天天联盟,wordpress 给标签加id,wordpress缩小模块间距,苏州比较好的建筑公司#x1f341;你好#xff0c;我是 RO-BERRY #x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 #x1f384;感谢你的陪伴与支持 #xff0c;故事既有了开头#xff0c;就要画上一个完美的句号#xff0c;让我们一起加油 目录 1.进程间通信目的2. 什么… 你好我是 RO-BERRY 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 感谢你的陪伴与支持 故事既有了开头就要画上一个完美的句号让我们一起加油 目录 1.进程间通信目的2. 什么是进程间通信3. 进程间通信发展4.如何进行进程间通信4.1 一般规律4.2 具体做法 5.进程间通信分类6. 管道匿名管道用fork来共享管道原理站在文件描述符角度-深度理解管道验证管道通信代码 1.进程间通信目的 两个进程之间可以进行“数据”的直接传递吗不能进程具有独立性 那么为什么需要进程间通信呢
数据传输一个进程需要将它的数据发送给另一个进程 在很多场景之间两个进程需要进行数据传输比如A进程负责获取网络中的数据但是它并不会去处理这份数据而B进程为只负责处理数据这样就可以实现多进程的并发 资源共享多个进程之间共享同样的资源。 有一部分进程需要进行共享一份资源以便于两进程共同访问共同完成一件事情比如说我们玩游戏多玩家在同一局游戏中我们看到的数据都是一模一样的我们的每个用户也就是一个进程我们对于地图资源进行的是共享 通知事件一个进程需要向另一个或一组进程发送消息通知它它们发生了某种事件如进程止时要通知父进程。进程控制有些进程希望完全控制另一个进程的执行如Debug进程此时控制进程希望能够拦截另一个进程的所有陷入和异常并能够及时知道它的状态改变 2. 什么是进程间通信 进程间通信Inter-process CommunicationIPC是指在多道程序环境下进程间进行数据交换和信息传递的一种机制或方法。在现代操作系统中进程是系统资源分配的基本单位不同进程之间需要相互合作和通信才能完成各种任务。进程间通信是实现进程间协作的重要手段。 常用的进程间通信方式有管道、消息队列、共享内存、信号量和套接字等。管道是一种半双工的通信方式消息队列是一种异步通信方式共享内存是一种高效的通信方式信号量是一种用于同步进程的通信方式套接字是一种网络通信方式。 3. 进程间通信发展
进程间通信是指不同进程之间的数据交换和共享是操作系统中非常重要的一个概念。随着计算机技术的发展进程间通信也经历了多个发展阶段。 第一阶段是管道它是Unix系统中最早的进程间通信方式可以在两个相关进程之间传递数据。 第二阶段是信号它是Unix系统中另一种进程间通信方式用于通知接收进程某个事件已经发生。 第三阶段是共享内存它可以允许多个进程访问同一块物理内存从而实现数据共享。 第四阶段是消息队列它可以在不同进程之间传递消息实现进程间通信。 第五阶段是套接字它可以在不同主机之间传递数据并且支持多种通信协议。 第六阶段是远程过程调用RPC它允许程序员在不同计算机上运行的程序之间进行交互。 4.如何进行进程间通信
4.1 一般规律
进程间通信的本质让不同的进程看到同一份资源一般都是由OS提供
进程间通信需要一个另外的交换数据的空间内存 此交换空间不能由通信双方任何一方进行提供如果提供了空间让对方进程来进行访问这就有违背进程独立性所以我们需要另一个额外空间进行数据的传输这种事情会有OS来进行操作 4.2 具体做法
OS提供的“空间”有不同的样式这决定了不同的通信方式
常见通信方式
管道匿名和命名共享内存消息队列信号量 5.进程间通信分类
管道
匿名管道pipe命名管道
System V IPC System V IPC是指System V操作系统提供的进程间通信IPC机制它允许进程在不同的计算机系统之间进行通信和同步。System V IPC主要包括三种类型的通信机制消息队列、共享内存和信号量。 System V 消息队列System V 共享内存System V 信号量
POSIX IPC POSIX IPC 是指可移植操作系统接口Portable Operating System Interface缩写为POSIX中的进程间通信Inter-Process Communication缩写为IPC机制。它提供了一组标准的函数和数据结构用于在不同的进程间进行数据交换和同步操作。常用的 POSIX IPC 包括消息队列、共享内存、信号量等。使用 POSIX IPC 可以实现不同进程之间的数据共享和通信进而实现更加复杂的多进程协作模式。 消息队列共享内存信号量互斥量条件变量读写锁 6. 管道
管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”
管道是一种进程间通信机制它可以用来在不同进程间传递数据。在底层实现上管道其实是一种内核缓冲区它由两个文件描述符文件句柄表示一个用于读取一个用于写入。当一个进程向管道中写入数据时数据会被存储到内核缓冲区中另一个进程则可以从同一个管道中读取这些数据。
管道底层实现的关键是通过操作系统提供的内核缓冲区实现进程间的数据传输。管道有两个缓冲区分别用于存储读取和写入的数据。当写入进程向管道中写入数据时数据会被存储到写入缓冲区中。如果写入缓冲区已满则写入进程会被阻塞直到有足够的空间来存储数据。当读取进程从管道中读取数据时数据会从读取缓冲区中读取。如果读取缓冲区为空则读取进程也会被阻塞直到有新的数据可供读取。
需要注意的是管道具有单向性即数据只能从一个方向流动。如果需要双向通信则需要创建两个管道。同时在管道中传递的数据是没有结构的字节流因此需要约定好传递的数据格式以及数据长度。
匿名管道
#include unistd.h
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0失败返回错误代码这个函数让我们不需要向磁盘中刷新并且磁盘中并不存在文件其本质就是会创建一个内存级的文件这个文件没有名字为匿名文件(管道)
匿名管道如何做到让不同的进程看到同一份资源 就是利用了创建子进程子进程会创建父进程的相关属性信息匿名管道可以只能进行具有血缘关系的进程进行进程间通信常用于父子 实例代码
例子从键盘读取数据写入管道读取管道写到屏幕
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
int main(void)
{int fds[2];char buf[100];int len;if (pipe(fds) -1)perror(make pipe), exit(1);// read from stdinwhile (fgets(buf, 100, stdin)) {len strlen(buf);// write into pipeif (write(fds[1], buf, len) ! len) {perror(write to pipe);break;}memset(buf, 0x00, sizeof(buf));// read from pipeif ((len read(fds[0], buf, 100)) -1) {perror(read from pipe);break;}// write to stdoutif (write(1, buf, len) ! len) {perror(write to stdout);break;}}
}用fork来共享管道原理 站在文件描述符角度-深度理解管道 为什么父进程最开始就要按照r和w打开同一个文件呢 这是因为管道只允许一个人读一个人写。 验证管道通信代码
#includestdio.h
#includestring.h
#includestdlib.h
#includeunistd.h
#includesys/types.h
#includesys/wait.hvoid writer(int wfd)
{const char *str hello father, I am child;char buffer[128];int cnt 0;pid_t pid getpid();while(1){snprintf(buffer, sizeof(buffer),message: %s,pid: %d,count: %d \n, str, pid, cnt);write(wfd,buffer,strlen(buffer)1);cnt;sleep(1);}
}
void reader(int rfd)
{char buffer[1024];while(1){ssize_t n read(rfd, buffer, sizeof(buffer)-1);(void)n; //读取但是没有用printf(father get a message: %s, buffer);}
}int main()
{int pipefd[2];int n pipe(pipefd);if(n0) return 1;printf(pipefd[0]: %d, pipefd[1]: %d\n, pipefd[0]/*read*/, pipefd[1])/*write*/; //创建管道//父子进程pid_t idfork();if(id 0){//child 实现W 关闭读取保留写入close(pipefd[0]);writer(pipefd[1]);exit(0);}//father实现rclose(pipefd[1]);reader(pipefd[0]);wait(NULL);return 0;
} 这里可以在左边看到有两个进程同时运行初步实现管道通信子进程可以写给父程序