Linux 和 Windows 下实现多进程的方式以及管道操作
1.windows 多进程
使用 #include<windows.h> 下面的
BOOL CreateProcess(
LPCWSTR pszImageName, LPCWSTR pszCmdLine,
LPSECURITY_ATTRIBUTES psaProcess,
LPSECURITY_ATTRIBUTES psaThread,
BOOL fInheritHandles, DWORD fdwCreate,
LPVOID pvEnvironment, LPWSTR pszCurDir,
LPSTARTUPINFOW psiStartInfo,
LPPROCESS_INFORMATION pProcInfo
);
其中几个关键的形参为:
STARTUPINFO sui;
PROCESS_INFORMATION pi;
ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb = sizeof(STARTUPINFO);
sui.dwFlags = STARTF_USESTDHANDLES;
sui.hStdInput = hRead;
sui.hStdOutput = hWrite;
sui.hStdError = GetStdHandle(STD_ERROR_HANDLE);
CreateProcess("../.../run/Chilid.exe",NULL,NULL,NULL,TRUE,,NULL,NULL,&sui,&pi);
参数pszCmdLine //用来指定传递给新进程的命令行字符串
TCHAR szApp[MAX_PATH] = TEXT("netstat -s");
CreateProcess(NULL,szApp,NULL,NULL,TRUE,,NULL,NULL,&sui,&pi);
typedef struct _STARTUPINFOA {
DWORD cb;
LPSTR lpReserved;
LPSTR lpDesktop;
LPSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFOA, *LPSTARTUPINFOA;
对于 dwFlags 参数来说,如果其设置为 STARTF_USESTDHANDLES ,则将会使用该 STARTUPINFO 结构体中的 hStdInput , hStdOutput , hStdError 成员,来设置新创 建的进程的标准输入,标准输出,标准错误句柄。
参数 pProcInfo //为一个输出参数,指向一个 PROCESS_INFORMATION 结构体的指针,用来接收关于新进程的标识信息。
其中 hProcess 和 hThread 分别用来标识新创建的进程句柄和新创建的进程的主线程句柄。
dwProcessId 和 dwThreadId 分别是全局进程标识符和全局线程标识符。前者可以用来标识一个进程,后者用来标识一个线程
typedef struct _PROCESS_INFORMATION
{ HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
}PROCESS_INFORMATION;
【注】CreateProcess()和CreateThread()的区别,是前者创建的是进程,而后者创建的是线程。
<unistd.h> ---- exec系列;
<stdlib.h> ---- sysytem();
e.g
system("cd /home/root/");
【注】linux下创建线程的方式
<pthread.h> ---- pthread_create
e.g:
int * thread(void *arg){}
pthread_t id; //记录创建线程的id
pthread_create(&id,NULL,(void*) thread,NULL);
二、管道
1、windows 下的管道
a. 匿名管道 -- 进程和其子进程之间通信
#include<iostream>
#include <windows.h>
#define MAX_PATH 1024
using namespace std;
int main(){
TCHAR szApp[MAX_PATH] = TEXT("netstat -s");
char ReadBuf[];
DWORD ReadNum;
HANDLE hRead = NULL; // 管道读句柄
HANDLE hWrite = NULL; // 管道写句柄
SECURITY_ATTRIBUTES sa = {};
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
bool bRet = CreatePipe(&hRead, &hWrite, &sa, );
if (bRet)
{
cout<<"创建管道成功"<<endl;
}
else{
cout<<"创建管道失败"<<endl;
}
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi = {};
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdOutput = hWrite;
si.hStdError = hWrite;
si.wShowWindow = SW_HIDE;
HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);
GetStartupInfo(&si);
bRet = CreateProcess(NULL,szApp,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi); //创建一个执行命令行的进程
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWrite);
int i = ;
while(ReadFile(hRead,ReadBuf,,&ReadNum,NULL)){ //对管道进行读操作
ReadBuf[ReadNum] = '\0';
cout<<"panfei"<<endl;
cout<<i++<<endl;
//cout<<ReadBuf<<endl;
}
if(GetLastError() == ERROR_BROKEN_PIPE)
cout<<"管道被子进程关闭"<<endl;
ExitProcess();
return ;
}
b. 命名管道 -- 可以实现两个无任何亲缘关系的进程之间的数据传递
server端:
#include <iostream>
#inserclude <Windows.h>
HANDLE hpipe = INVALID_HANDLE_VALUE;
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); //★管道的名称必须这样命名,托付给系统管理
int main(){
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
hpipe = CreateNamedPipe( //创建命名pipe
lpszPipename, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZ, // output buffer size
BUFSIZ, // input buffer size
, // client time-out
NULL); // default security attribute
if (hpipe == INVALID_HANDLE_VALUE)
{
cout<<"CreateNamedPipe failed, GLE=%d.\n"<<endl;;
return -;
}
BOOL fConnected = ConnectNamedPipe(hpipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); //等待有其他进程连接该pipe ,一旦有进程连接该pipe,下面的代码才会执行
char buf[] = {'a','b','a','\0'};
WriteFile(hpipe,buf,,NULL,NULL);
return ;
}
client端:
int main(){
hPipe = CreateFile( //连接server创建的pipe
lpszPipename, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
, // default attributes
NULL); // no template file
DWORD dwMode = PIPE_READMODE_MESSAGE;
BOOL fSuccess = SetNamedPipeHandleState( //设置管道的状态,设置到读取状态
hPipe, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
DWORD cbRead;
fSuccess = ReadFile( //读取管道中的数据
hPipe, // pipe handle
readBuf, // buffer to receive reply
BUFSIZ*sizeof(TCHAR), // size of buffer
&cbRead, // number of bytes read
NULL); // not overlapped
cout<<readBuf<<endl;
}
2. Linux 下的管道
a. 匿名管道
e.g
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(){
int pfd[]; //用于保存打开管道后的两个文件描述符号
pid_t cpid; //进程id
char buf;
if(pipe(pfd) == -){
fprintf("Pipe created fail!");
}
cpid = fork();
if(cpid == ){
close(pfd[]); //读管道前关闭管道写端
while(read(pfd[],&buf,){ //读取管道
printf("%s\n",buf);
}
exit() //退出子进程
}
else{
char writeBuf[] = {'a','b','c'};
close(pfd[]);
wirte(pfd[],writeBuf,sizeof(writeBuf)); //向管道中写入数据
exit();
}
}
b. 命名管道
参考:http://www.cppblog.com/wanghaiguang/archive/2012/11/20/195412.html
Linux 和 Windows 下实现多进程的方式以及管道操作的更多相关文章
- [笔记]linux下和windows下的 创建线程函数
linux下和windows下的 创建线程函数 #ifdef __GNUC__ //Linux #include <pthread.h> #define CreateThreadEx(ti ...
- tar.xz如何解压:linux和windows下tar.xz解压命令介绍
在linux下怎么解压和压缩tar.xz文件? (本文由www.169it.com搜集整理) 在linux下解压tar.xz文件步骤 1 2 # xz -d ***.tar.xz //先解压xz # ...
- 从Docker在Linux和Windows下的区别简单理解Docker的层次结构
上篇文章我们成功在Windows下安装了Docker,输出了一个简单的Hello World程序.本文中我们将利用Docker已有的云端镜像training/webapp来发布一个简单Python的W ...
- 【转】linux和windows下安装python集成开发环境及其python包
本系列分为两篇: 1.[转]windows和linux中搭建python集成开发环境IDE 2.[转]linux和windows下安装python集成开发环境及其python包 3.windows和l ...
- protobuff 配合 libevent 在Linux 和windows 下的使用
protobuff 配合 libevent 在Linux 和windows 下的使用待补全. libprotobuf.lib libproto-lite.lib libprotoc.lib
- Linux/centos/redhat下各种压缩解压缩方式详解
1.zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip unzip -o -d ...
- Linux和Windows下查看环境变量方法对比
摘自:Linux和Windows下查看环境变量方法对比 一.查看所有环境变量的名称和值 Linux下:export Windows下:set 二.根据名称查该环境变量的值 Linux下:echo $环 ...
- Golang 在 Mac、Linux、Windows 下如何交叉编译(转)
原文地址:Golang 在 Mac.Linux.Windows 下如何交叉编译 Golang 支持交叉编译,在一个平台上生成另一个平台的可执行程序,最近使用了一下,非常好用,这里备忘一下. Mac 下 ...
- linux和windows下TIME_WAIT过多的解决办法
http://www.51testing.com/html/48/202848-249774.html linux和windows下TIME_WAIT过多的解决办法 http://m.sohu.com ...
随机推荐
- 剖析Asp.Net路由系统
对于Asp.Net Web Forms应用来说,请求的Url都是对应一个具体的物理文件(http://xxx.com/default.aspx).这样的Url与具体物理文件紧密绑定在一起,带来了诸多方 ...
- OSS项目进度(2.19)
前两周先后完成了OSS.Common ,OSS.Http ,OSS.Social 项目的.net standard支持,再次开始进入框架本身的开发,今天进度情况: 一.OSS.Social 完成摇一摇 ...
- GCD(关于容斥原理)
Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD( ...
- linux编译内核
ubuntu 14.04 编译内核出现unable to locate package ncurses-devel 问题的解决 首先,在make menuconfig的时候就会提示没有 nucrs ...
- [APUE]进程关系(上)
一.终端登录 1. 4.3+BSD终端登录 系统管理员创建一个通常名为/etc/ttys的文件,其中,每个终端设备有一行,每一行说明设备名和传到getty程序的参数,这些参数说明了终端的波特率.当系统 ...
- unity3d 脚本学习系列
最近使用unity3d,对其中的脚本部分进一系列总结,算是这一段时间的收获吧.
- javaweb 打包为安卓apk(1)-Hbuilder
需求:当前已经完成java web项目开发,java web项目前端使用自适应框架(bootstrap),想使用最简单方式生成一个安卓apk,无需进行安卓开发(类似于手机浏览器访问一样) 要求:项目已 ...
- 关于select count
关于select count,之前有一些不清楚的地方,看到阿里巴巴的Java编程规范,sql规约的第一条就是关于select count的 需要明确以下两点: 1.select count(常量)和s ...
- JavaWeb从0开始学(一)-----搭建第一个Web应用程序与JSP工作原理
以往学习的时候大多是看完书或者看完视频,动手实践一下就OK了.然而过了一段时间我发现东西都忘差不多了,需要复习才能重新掌握.现在开始学习JavaWeb了,我将在这里记录自己的学习的一点一滴,不仅便于自 ...
- 前端总结·基础篇·JS(一)五大数据类型之字符串(String)
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(二)补充 前端总结·基础篇·JS(一)五大数据类型之字符串(String) 目录 这是& ...