Linux 和 Windows 下实现多进程的方式以及管道操作

一、多进程

1.windows 多进程

使用 #include<windows.h> 下面的

1 BOOL  CreateProcess( 

2         LPCWSTR pszImageName,  LPCWSTR pszCmdLine, 

3         LPSECURITY_ATTRIBUTES psaProcess, 

4         LPSECURITY_ATTRIBUTES psaThread, 

5         BOOL fInheritHandles,  DWORD fdwCreate, 

6         LPVOID pvEnvironment,  LPWSTR pszCurDir, 

7         LPSTARTUPINFOW psiStartInfo, 

8         LPPROCESS_INFORMATION pProcInfo 

9 );
View Code

其中几个关键的形参为:

    参数pszImageName   //指向一个NULL终止的字符串,用来指定可执行程序的名字。
     e.g:
1 STARTUPINFO sui;

2 PROCESS_INFORMATION pi;

3 ZeroMemory(&sui,sizeof(STARTUPINFO));

4 sui.cb = sizeof(STARTUPINFO);

5 sui.dwFlags = STARTF_USESTDHANDLES;

6 sui.hStdInput = hRead;

7 sui.hStdOutput = hWrite;

8 sui.hStdError = GetStdHandle(STD_ERROR_HANDLE);

9         CreateProcess("../.../run/Chilid.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi);
View Code

      参数pszCmdLine    //用来指定传递给新进程的命令行字符串

     e.g:
1  TCHAR szApp[MAX_PATH] = TEXT("netstat -s");

2           CreateProcess(NULL,szApp,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi);
View Code
      参数psiStartInfo   //指向一个 StartUpInfo 的结构体的指针,用来指定新进程的主窗口如何显示
 1 typedef struct _STARTUPINFOA {

 2     DWORD cb;

 3     LPSTR lpReserved;

 4     LPSTR lpDesktop;

 5     LPSTR lpTitle;

 6     DWORD dwX;

 7     DWORD dwY;

 8     DWORD dwXSize;

 9     DWORD dwYSize;

10     DWORD dwXCountChars;

11     DWORD dwYCountChars;

12     DWORD dwFillAttribute;

13     DWORD dwFlags;

14     WORD wShowWindow;

15     WORD cbReserved2;

16     LPBYTE lpReserved2;

17     HANDLE hStdInput;

18     HANDLE hStdOutput;

19     HANDLE hStdError;

20 } STARTUPINFOA, *LPSTARTUPINFOA;
View Code

      对于 dwFlags 参数来说,如果其设置为 STARTF_USESTDHANDLES ,则将会使用该 STARTUPINFO 结构体中的     hStdInput , hStdOutput , hStdError 成员,来设置新创       建的进程的标准输入,标准输出,标准错误句柄。

      参数 pProcInfo    //为一个输出参数,指向一个 PROCESS_INFORMATION 结构体的指针,用来接收关于新进程的标识信息。

      其中 hProcess 和 hThread 分别用来标识新创建的进程句柄和新创建的进程的主线程句柄。

      dwProcessId 和 dwThreadId 分别是全局进程标识符和全局线程标识符。前者可以用来标识一个进程,后者用来标识一个线程

1 typedef struct _PROCESS_INFORMATION 

2 {   HANDLE hProcess;             

3     HANDLE hThread;             

4     DWORD dwProcessId;              

5     DWORD dwThreadId; 

6 }PROCESS_INFORMATION;
View Code

【注】CreateProcess()和CreateThread()的区别,是前者创建的是进程,而后者创建的是线程。

2. Linux下多进程
     Linux创建线程的主要方式有:
     <unistd.h> ---- fork();

    <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. 匿名管道 -- 进程和其子进程之间通信

 1 #include<iostream>

 2 #include <windows.h>

 3 #define MAX_PATH 1024

 4 using namespace std;

 5 int main(){

 6 TCHAR szApp[MAX_PATH] = TEXT("netstat -s");

 7  char ReadBuf[100];

 8  DWORD ReadNum;

 9  HANDLE hRead = NULL; // 管道读句柄

10  HANDLE hWrite = NULL; // 管道写句柄

11     SECURITY_ATTRIBUTES sa = {0};

12     sa.nLength = sizeof(sa);  

13     sa.lpSecurityDescriptor = NULL;  

14     sa.bInheritHandle = TRUE;  

15     bool bRet = CreatePipe(&hRead, &hWrite, &sa, 0);

16     if (bRet)

17     {

18      cout<<"创建管道成功"<<endl;

19     }

20     else{

21      cout<<"创建管道失败"<<endl;

22     }

23     STARTUPINFO si = {sizeof(si)};  

24     PROCESS_INFORMATION pi = {0};  

25     si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;    

26     si.hStdOutput = hWrite;  

27     si.hStdError = hWrite;  

28     si.wShowWindow = SW_HIDE;  

29     HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);

30     GetStartupInfo(&si);

31     bRet = CreateProcess(NULL,szApp,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi);  //创建一个执行命令行的进程

32     CloseHandle(pi.hThread);  

33     CloseHandle(pi.hProcess);  

34     CloseHandle(hWrite);  

35     int i = 0;

36     while(ReadFile(hRead,ReadBuf,1024,&ReadNum,NULL)){       //对管道进行读操作           

37      ReadBuf[ReadNum] = '\0';

38         cout<<"panfei"<<endl;

39         cout<<i++<<endl;

40      //cout<<ReadBuf<<endl;

41     }

42     if(GetLastError() == ERROR_BROKEN_PIPE)

43      cout<<"管道被子进程关闭"<<endl;

44     ExitProcess(0);

45  return 0;

46 }
View Code

     b. 命名管道 -- 可以实现两个无任何亲缘关系的进程之间的数据传递

       server端:

 1 #include <iostream>

 2         #inserclude <Windows.h>

 3         HANDLE hpipe = INVALID_HANDLE_VALUE;

 4         LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");    //★管道的名称必须这样命名,托付给系统管理

 5         int main(){

 6  SECURITY_ATTRIBUTES sa;

 7  sa.bInheritHandle = TRUE;

 8  sa.lpSecurityDescriptor = NULL;

 9  sa.nLength = sizeof(SECURITY_ATTRIBUTES);

10  hpipe = CreateNamedPipe(                                                //创建命名pipe

11   lpszPipename,             // pipe name

12   PIPE_ACCESS_DUPLEX,       // read/write access

13   PIPE_TYPE_MESSAGE |       // message type pipe

14   PIPE_READMODE_MESSAGE |   // message-read mode

15   PIPE_WAIT,                // blocking mode

16   PIPE_UNLIMITED_INSTANCES, // max. instances  

17   BUFSIZ,                   // output buffer size

18   BUFSIZ,                   // input buffer size

19   0,                        // client time-out

20   NULL);                    // default security attribute

21  if (hpipe == INVALID_HANDLE_VALUE)

22  {

23   cout<<"CreateNamedPipe failed, GLE=%d.\n"<<endl;;

24   return -1;

25  }

26  BOOL fConnected = ConnectNamedPipe(hpipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);   //等待有其他进程连接该pipe ,一旦有进程连接该pipe,下面的代码才会执行

27  char buf[1024] = {'a','b','a','\0'};

28  WriteFile(hpipe,buf,3,NULL,NULL);

29  return 0;

30 }
View Code

 client端:

 1  int main(){

 2              hPipe = CreateFile(             //连接server创建的pipe

 3                       lpszPipename,   // pipe name

 4                       GENERIC_READ |  // read and write access

 5                       GENERIC_WRITE,

 6                       0,              // no sharing

 7                       NULL,           // default security attributes

 8                       OPEN_EXISTING,  // opens existing pipe

 9                       0,              // default attributes

10                       NULL);          // no template file 

11               DWORD dwMode = PIPE_READMODE_MESSAGE;

12               BOOL fSuccess = SetNamedPipeHandleState(            //设置管道的状态,设置到读取状态

13               hPipe,    // pipe handle

14               &dwMode,  // new pipe mode

15               NULL,     // don't set maximum bytes

16                                     NULL);    // don't set maximum time

17               DWORD cbRead;

18               fSuccess = ReadFile(                                        //读取管道中的数据

19               hPipe,    // pipe handle

20               readBuf,    // buffer to receive reply

21               BUFSIZ*sizeof(TCHAR),  // size of buffer

22               &cbRead,  // number of bytes read

23                NULL);    // not overlapped

24               cout<<readBuf<<endl;

25         }
View Code

2.  Linux 下的管道

     a. 匿名管道  

      e.g

 1  #include<stdio.h>

 2            #include<stdlib.h>

 3            #include<unistd.h>

 4            int main(){

 5                 int pfd[2];                  //用于保存打开管道后的两个文件描述符号

 6                 pid_t cpid;                 //进程id

 7                 char buf;

 8                 if(pipe(pfd) == -1){

 9                       fprintf("Pipe created fail!");

10                 }

11                 cpid = fork();

12                 if(cpid == 0){

13                        close(pfd[1]);       //读管道前关闭管道写端

14                        while(read(pfd[0],&buf,1){     //读取管道

15                             printf("%s\n",buf);

16                         }

17                         exit(1)                //退出子进程

18                 }

19                 else{

20                       char writeBuf[3] = {'a','b','c'};

21                       close(pfd[0]);

22                       wirte(pfd[1],writeBuf,sizeof(writeBuf));     //向管道中写入数据

23                       exit(0);

24                 }

25            }
View Code

     b. 命名管道

 参考:http://www.cppblog.com/wanghaiguang/archive/2012/11/20/195412.html

你可能感兴趣的:(windows)