Windows进程间利用管道通信

news2024/10/7 4:32:50

实验一

一、实验内容或题目:

在父进程中创建一个子进程,并建立一个管道,子进程向管道中写入一个字符串,父进程从管道中读出字符串。

二、实验目的与要求:

利用CRT相关接口,学习在父子进程间实现管道通信。

三、实验步骤(以windows和Visual Studio为例):

1、建立解决方案和项目(略)
2、参照课本3.7.5章节的例1,利用CRT LIB提供的相似性接口,实现相同的功能(使用Linux的同学调用相应的接口)
3、CRT相关api:_pipe, _spawn, _cwait, _read, _write。示例代码可以参照 :https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/pipe?view=msvc-160

四、实验结果:

1)对示例代码的详细批注
在这里插入图片描述
在这里插入图片描述

#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <process.h>
#include <math.h>

enum PIPES { READ, WRITE };
#define NUMPROBLEM 8

int main(int argc, char* argv[])
{
    int  i;
    int fdpipe[2];
    char hstr[20];
    int pid, problem, c;
    int termstat;
    //如果是父进程argc则会等于1,子进程则等于2、3...
    if (argc == 1)
    {
        //定更改流输出流没有缓冲罐
        setvbuf(stdout, NULL, _IONBF, 0);

        //fdpipe:两个指针,用于保存读和些写描述
        if (_pipe(fdpipe, 256, O_BINARY) == -1)
            exit(1);

        //_itoa_s:将整数转换成字符串的函数,让fdpipe[READ]可以存入字符串,使得管道可以存放传输字符串
        _itoa_s(fdpipe[READ], hstr, sizeof(hstr), 10);

        //_spawnl:创建子进程,启动子进程再次执行main()
        if ((pid = _spawnl(P_NOWAIT, argv[0], argv[0], hstr, NULL)) == -1)
            printf("Spawn failed");

        for (problem = 1000; problem <= NUMPROBLEM * 1000; problem += 1000)
        {
            printf("From parent:the number is %d\n", problem);
            //向fdpipe[WRITE]写入数据problem
            _write(fdpipe[WRITE], (char*)&problem, sizeof(int));

        }
        printf("dsa");
        //等待子进程结束,回收子进程
        _cwait(&termstat, pid, WAIT_CHILD);
        if (termstat & 0x0)
            printf("Child failed\n");
        _close(fdpipe[READ]);
        _close(fdpipe[WRITE]);

    }
    else
    {
        //atoi:将参数转换为整数
        fdpipe[READ] = atoi(argv[1]);
        for (c = 0; c < NUMPROBLEM; c++)
        {
            _read(fdpipe[READ], (char*)&problem, sizeof(int));
            printf("From child, the number is %d\n", problem);
        }
    }
}

2)由于持续报这个错误,或者无法运行,网上资料太少,官网的解释也没能太看懂,调试了几天,依然未能够解决,放弃了使用_sprawl(createProcess只是在创建子进程时比它能控制更多东西)。目前只能实现父给子传(官网例子),无法实现子给父传。
在这里插入图片描述
在这里插入图片描述
3)最后下载了Cygwin,该软件可以在Windows上仿真Linux操作系统,将其整合在了DEV C++中,使用Linux相关操作完成本实验。
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>

int main() 
{
	//两个文件描述符 ,fd[0]指向管道的读端(将fd文件传送到buf所指内存中),fd[1]指向管道的写端(将buf所指内存存入fd中) 
   	int pipefds[2];  
   	int status;
   	int pid;
   	char writemessage[40];
   	char readmessage[40];
    
   	status = pipe(pipefds);
   	if (status == -1) 
	{
      	printf("Failed to create pipe");
      	return 0;
   	}
   
   	//创建子进程 
   	pid = fork();
   	
   	if (pid == 0) 
	{
   		//子进程 
   		strcpy(writemessage, "I am the child process");
    	printf("From child process: %s\n", writemessage);
      	write(pipefds[1], writemessage, sizeof(writemessage));
   	} 
	else 
	{ 
      	//父进程 
      	read(pipefds[0], readmessage, sizeof(readmessage));
      	printf("From parent process: %s\n", readmessage);
      	close(pipefds[0]);
    	close(pipefds[1]);
    }
	return 0;
}

在这里插入图片描述

总结

使用Linux来完成程序,使得可读性比较好,便于分析,利于初步学习。对于Windows报错的原因,我目前觉得原因是“fdpipe[0] = atoi(argv[1])”这里的问题,访问了野指针。argv[1]这个参数究竟能干什么,也不是特别清除,打印出来只是一个数字,但不这样写就无法运行,如果直接用属性中高级设置给argv[1]它一个值也不行。但根据示例代码,在read之前要使用这条语句转变fdpipe[0],如果让父进程来read,父进程是没有argv[1]的,可能因为该数据不共享,如果在子进程使用这条语句也无法传给父进程,目前还找不到解决方式。

实验二

一、实验内容或题目

在父进程中创建两个子进程,并建立一个管道,两个子进程分别向管道中写入一个字符串,父进程从管道中读出字符串。

二、实验目的与要求:

利用CRT相关接口,学习在父子进程间实现一对多的管道通信。

三、实验步骤:

1、建立解决方案和项目(略)
2、参照课本3.7.5章节的例2,利用CRT LIB提供的相似性接口,实现相同的功能(使用Linux的同学调用相应的接口)
3、CRT相关api:_pipe, _spawn, _cwait, _read, _write。示例代码可以参照 :https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/pipe?view=msvc-160

四、实验结果:

1)让子进程再fork出一个子进程
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>

int main() 
{
   	int pipefds[2];  
   	int status;
   	int pid1, pid2;
   	char writemessage[40];
   	char readmessage[40];
   
   	status = pipe(pipefds);
   	if (status == -1) 
	{
      	printf("Failed to create pipe");
      	return 0;
   	}
   
   	//创建子进程 
   	pid1 = fork();
   	//一个fork得放里面,否则子进程执行时会在多创建一个进程 
   	if (pid1 == 0) 
	{
   		//子进程2
   		strcpy(writemessage, "I am No.1");
    	printf("From child process: %s\n", writemessage);
      	write(pipefds[1], writemessage, sizeof(writemessage));
      	pid2 = fork();
      	if (pid2 == 0) 
		{
   			//子进程2
   			strcpy(writemessage, "I am No.2");
    		printf("From child process: %s\n", writemessage);
      		write(pipefds[1], writemessage, sizeof(writemessage));
      		return 0;
   		} 
      	return 0;
   	} 
	if (pid1 != 0) 
	{ 
      	//父进程 
      	sleep(2);
      	read(pipefds[0], readmessage, sizeof(readmessage));
		printf("From parent process: %s\n", readmessage);
      	read(pipefds[0], readmessage, sizeof(readmessage));
      	printf("From parent process: %s\n", readmessage);
      	close(pipefds[0]);
    	close(pipefds[1]);
    }
	return 0;
}

在这里插入图片描述
2)在父进程下fork出两个子进程
在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>

int main() 
{
	int pipefds[2];  
   	int status;
   	int pid;
   	char writemessage[40];
   	char readmessage[40];
   
   	status = pipe(pipefds);
   	if (status == -1) 
	{
      	printf("Failed to create pipe");
      	return 0;
   	}
   
   	//创建子进程 
   	for (int i = 0; i <= 1; i++) 
	{	
		pid = fork();
		if (pid == 0)
			break;
	}
   	if (pid == 0) 
	{
   		strcpy(writemessage, "I am a child");
    	printf("From child process: %s\n", writemessage);
      	write(pipefds[1], writemessage, sizeof(writemessage));
      	return 0;
   	} 
   	else
	{ 
      	sleep(2);
      	read(pipefds[0], readmessage, sizeof(readmessage));
		printf("From parent process: %s\n", readmessage);
		read(pipefds[0], readmessage, sizeof(readmessage));
		printf("From parent process: %s\n", readmessage);
      	close(pipefds[0]);
    	close(pipefds[1]);
    }
    return 0;
}

在这里插入图片描述

五、总结:

在这里插入图片描述
在这里插入图片描述
通过这个实验发现,fork创建进程还是比较复杂的,简单说明一下这个执行过程。在没有使用“setvbuf(stdout, NULL, _IONBF, 0)”,它的输出是第一张图这样的,起初我以为,每次fork一个子进程,子进程都会重新执行main,父进程则继续执行(根据图片输出其实也不是,如果是这个逻辑则应该输出,第一行则应该是aaaabbbbaaaabbbbFrom等,所以很困惑),但查阅资料后,知道父进程执行过的代码子进程不会执行,所以想到了Windows示例代码中使用的setvbuf,使得输出没有缓冲(具体怎么缓冲也不是特别清楚),然后输出为第二张图,至此结合第三张图也大概理解了整个流程,最关键的就是“父进程执行过的代码子进程不会执行”,为了不让子进程在循环中再在自己的进程中发动fork,只需加个判断,使得子进程退出循环。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/20057.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

酒水商城|基于Springboot实现酒水商城系统

作者主页&#xff1a;编程千纸鹤 作者简介&#xff1a;Java、前端、Pythone开发多年&#xff0c;做过高程&#xff0c;项目经理&#xff0c;架构师 主要内容&#xff1a;Java项目开发、毕业设计开发、面试技术整理、最新技术分享 收藏点赞不迷路 关注作者有好处 项目编号&…

【Java八股文总结】之集合

文章目录Java集合一、集合概述1、List、Set、Queue、Map的区别&#xff1f;2、Collections和Collection的区别&#xff1f;3、集合和数组的区别二、List1、ArrayList和LinkedList的区别&#xff1f;2、ArrayList和Vector的区别3、Vector、ArrayList和LinkedList的区别4、ArrayL…

Echarts:简单词云图实现

Echarts是一个开源的可视化图表库&#xff0c;支持丰富的图表&#xff0c;官网中还有大量示例可以选择使用、参考。 其中比较好玩、有趣的是词云&#xff0c;词云就是用关键词组成的一朵云&#xff0c;更广泛的定义是&#xff0c;由关键词组成的任意一种图案均称为词云。因此&…

[附源码]java毕业设计社区空巢老人关爱服务平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【服务器】无法进行ssh连接的问题逐一排查以及解决方法

一、检查服务器网络 先检查是否是网络的问题。按快捷键WinR&#xff0c;在弹出的对话框中输入cmd。 点击确定运行。在cmd窗口输入ping一下服务器的ip地址。 如果出现请求超时&#xff0c;解决办法如下&#xff1a; 在服务器端输入ifconfig命令&#xff0c;查看要连接的网络的…

[计算机毕业设计]知识图谱的检索式对话系统

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过…

NX二次开发-调内部函数SEL_set_type_filter_index_by_label设置类型过滤器例子剖析怎么查找内部函数调用内部函数

NX二次开发-调内部函数SEL_set_type_filter_index_by_label设置类型过滤器例子剖析怎么查找内部函数调用内部函数 前言 给那些不会调内部函数的人,一个学习方法,大概知道怎么找内部接口,怎么调用内部函数的。 复杂的东西我也不会,等我研究出来了,在更新到博客上。 版本…

业务级灾备架构设计

同城多中心架构 同城双中心基本架构 关键特征&#xff1a; 相同城市&#xff0c;相距50km以上光纤互联机房间网络延时<2ms 同城双中心架构本质 同城双中心可以当做一个逻辑机房可以应对机房级别的灾难 同城双中心应用技巧-多光纤通路 同一集群&#xff0c;部署在同城两个…

异常~~~

异常 异常体系 编译时异常和运行时异常的区别 Java中的异常被分为两大类&#xff1a;编译时异常和运行时异常&#xff0c;也别成为受检异常和非受检异常 所有的RuntimeException类及其子类被称为运行时异常&#xff0c;其他的异常都是编译时异常 编译时异常&#xff1a;必须…

怎么在bios里设置光驱启动 bios设置光驱启动图文教程

大部分主板都是在开机以后按DEL键进入BIOS设置。 第一部分&#xff1a;学会各种bios主板的光驱启动设置&#xff0c;稍带把软驱关闭掉。 图1&#xff1a; 图2&#xff1a;光驱启动设置 。 图3&#xff1a;回车后要保存退出 。 图4&#xff1a;提示用户&#xff0c;必须选择“…

机器学习:BP神经网络

神经网络人工神经网络的结构特点人工神经网络单层神经网络双层神经网络多层神经网络BP神经网络通过TensorFlow实现BP神经网络单层感知网络是最初的神经网络&#xff0c;具有模型清晰、结构简单、计算量小等优点&#xff0c;但是它无法处理非线性问题。BP神经网络具有任意复杂的…

性能工具之前端分析工Chrome Developer Tools性能标签

文章目录一、前言二、第一部分三、第二部分四、第三部分五、第四部分六、小结一、前言 之前本博曾经写过几篇和前端性能分析相关的文章&#xff0c;如下&#xff1a; 常见性能工具一览性能工具之常见压力工具是否能模拟前端&#xff1f;性能工具之前端分析工Chrome Developer…

【Pytorch with fastai】第 19 章 :从零开始的 fastai 学习者

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

AutoDWG 文件属性编辑修改控件/Attribute Modifier-X

AutoDWG 文件属性编辑修改控件组件/AttributeX 控件组件 属性控件组件是开发者无需AutoCAD就可以直接在dwg文件中提取或修改属性值的组件。 主要特征&#xff1a; 从 dwg 文件中提取属性值。 直接在dwg文件中添加或修改属性值。 支持 R9 到 2016 版本的 DWG 和 DXF。 独立于 A…

如何学习Python技术?自学Python需要多久?

前言 Python要学习的时间取决于学习方式&#xff1a;自学至少需要学8个月;报班的话&#xff0c;可能需要4个月左右的时间。如果想具体了解Python要学多久&#xff0c;那不妨接着往下看吧! &#xff08;文末送读者福利&#xff09; 这个问题分为两种情况&#xff0c;分为自学和…

机械设计基础总复习

《机械设计基础》 一、简答题 1. 机构与机器的特征有何不同&#xff1f; 机器的特征&#xff1a;&#xff08;1&#xff09;人为机件的组合&#xff1b;&#xff08;2&#xff09;有确定的运动&#xff1b;&#xff08;3&#xff09;能够进行能量转换或代替人的劳动。 机构…

攻防世界Encode

Encode 题目描述&#xff1a;套娃&#xff1f; 题目环境&#xff1a;https://download.csdn.net/download/m0_59188912/87094879 打开timu.txt文件&#xff0c;猜测是rot13加密。 Rot13在线解码网址&#xff1a;https://www.jisuan.mobi/puzzm6z1B1HH6yXW.html 解密得到&#x…

跟艾文学编程《Python基础》(1)Python 基础入门

作者&#xff1a; 艾文&#xff0c;计算机硕士学位&#xff0c;企业内训讲师和金牌面试官&#xff0c;现就职BAT一线大厂公司资深算法专家。 邮箱&#xff1a; 1121025745qq.com 博客&#xff1a;https://wenjie.blog.csdn.net/ 内容&#xff1a;跟艾文学编程《Python基础入门》…

专题18:Django之Form,ModelForm

原始思路实现添加用户功能的缺点&#xff1a; 1&#xff09;用户提交的数据没有校验 2&#xff09;如果用户输入的数据有错误&#xff0c;没有错误提示 3&#xff09;前端页面上的每一个字段都需要我们重新写一次 4&#xff09;关联的数据需要手动取获取并循环展示在页面 1…

【Effective_Objective-C_1熟悉Objective_C】

文章目录说在前面的熟悉ObjectiveCfirst了解Objective-C的起源1.消息结构和函数调用运行期组件内存管理Objective-C的起源要点总结Second 在类的头文件尽量少饮入其他文件尽量延后引入头文件或者单独开辟一个文件向前声明在类的头文件尽量少饮入其他文件要点总结THIRD-多用字面…