Search within this blog

Tuesday, January 30, 2007

Creating Processes in Windows (Repost)

The following code illustrates how multiple processes can be spawned run in parallel under Windows. Here Windows API is used for system calls (like fork in Linux). The compiler I used is Microsoft Visual C++ 6.0.


There are three C source files:

  1. Win32Process1.c for Win32Process1.exe
  2. Win32Process2.c for Win32Process2.exe
  3. Win32MulProc.c for Win32MulProc.exe

Win32Process1 & Win32Process2 are similar. They both print integers 0 onwards with a specific delay between two integers. The delay can be specified by command line. If no delay is specified in command line then they goes for default delay which is set to 500ms.

Win32MulProc creates and runs Win32Process1 & Win32Process2 as child processes. It uses CreateProcess API call. Win32MulProc also has a loop that prints integers as before with specific delay. The delays for all 3 processes can be set by command line like
> Win32MulProc 500 250 250

The three processes the main one, Win32Process1 and Win32Process2 runs simultaneously.

The main process waits until the children completes.

CODES:

Win32Process1.c 1/27/2007

/**

* Win32Process1.c

* Code for Win32Process1.exe

*

* This is the code for the child process Win32Process1 which will be

* created by parent process Win32MulProc

*

* Author: Joydip Datta

* Date: 3:09 PM Saturday, January 27, 2007

*/

#include stdio.h

#include stdlib.h

#include windows.h

// a simple process thats counts 1 2 3 4 etc until Esc is hit

// a specific delay is imposed between each count

#define DEFAULT_DELAY 500 //ms

int main(int argc, char * argv[]) {

int delay, i, ch;

printf("\nProcess Win32Process1 started...\n");

if(argc>=2) //delay specified

delay = atoi(argv[1]);

else //delay not specified

delay = DEFAULT_DELAY;

for(i=0;;i++) {

if(kbhit())

if((ch=getch())==27)

break;

printf("Win32Process1: %d\n",i);

Sleep(delay);

}

printf("\nProcess Win32Process1 ended...\n");

}

Win32Process2.c 1/27/2007

/**

* Win32Process2.c

* Code for Win32Process2.exe

*

* This is the code for the child process Win32Process2 which will be

* created by parent process Win32MulProc

*

* Author: Joydip Datta

* Date: 3:09 PM Saturday, January 27, 2007

*/

#include stdio.h

#include stdlib.h

#include windows.h

// a simple process thats counts 1 2 3 4 etc until Esc is hit

// a specific delay is imposed between each count

#define DEFAULT_DELAY 500 //ms

int main(int argc, char * argv[]) {

int delay, i, ch;

printf("\nProcess Win32Process2 started...\n");

if(argc>=2) //delay specified

delay = atoi(argv[1]);

else //delay not specified

delay = DEFAULT_DELAY;

for(i=0;;i++) {

if(kbhit())

if((ch=getch())==27)

break;

printf("Win32Process2: %d\n",i);

Sleep(delay);

}

printf("\nProcess Win32Process2 ended...\n");

}

Win32MulProc.c 1/27/2007

/**

* Win32MulProc.c

* This is the parent process that calls and run two child processes

* Win32Process1.exe and Win32Process2.exe

* (and of course there is the main process)

* (To check how Windows handles multi programming)

*

* Author: Joydip Datta

* Date: 3:41 PM Saturday, January 27, 2007

*/

#include stdio.h

#include windows.h

#define DEFAULT_DELAY 500

#define PROCESS1 "Win32Process1"

#define PROCESS2 "Win32Process2"

int main(int argc, char* argv[])

{

STARTUPINFO si1,si2;

PROCESS_INFORMATION pi1,pi2;

int delayMain,delayP1,delayP2, i, ch;

char cmd1[50],cmd2[50]; //commands for two child processes

printf("\nProcess Main started...\n");

//delay calculation

if(argc>=4) {//delay specified

delayMain = atoi(argv[1]);

delayP1 = atoi(argv[2]);

delayP2 = atoi(argv[3]);

}

else //delay not specified

delayMain = delayP1 = delayP2 = DEFAULT_DELAY;

//setup commands

sprintf(cmd1,"%s %d",PROCESS1,delayP1);

sprintf(cmd2,"%s %d",PROCESS2,delayP2);

printf("\nPreparing to open two child processes...\n");

//CREATE 1ST PROCESS

//ALLOCATE MEMORY

ZeroMemory(&si1,sizeof(si1));

si1.cb=sizeof(si1);

ZeroMemory(&pi1,sizeof(pi1));

//create child process

if(! CreateProcess(NULL,

cmd1,

NULL,

NULL,

FALSE,

0,

NULL,

NULL,

&si1,

&pi1))

{

fprintf(stderr,"err: Win32Process1 creation failed");

return -1;

}

//CREATE 2ND PROCESS

//ALLOCATE MEMORY

ZeroMemory(&si2,sizeof(si2));

si2.cb=sizeof(si2);

ZeroMemory(&pi2,sizeof(pi2));

//create child process

if(! CreateProcess(NULL,

cmd2,

NULL,

NULL,

FALSE,

0,

NULL,

NULL,

&si2,

&pi2))

{

fprintf(stderr,"err: Win32Process2 creation failed");

return -1;

}

//loop for main process

for(i=0;;i++) {

if(kbhit())

if((ch=getch())==27)

break;

printf("Main: %d\n",i);

Sleep(delayMain);

}

printf("\nLoop of Process Main ended.\nBut Process Main will wait for her children...\n");

//parent will wait till child completes

WaitForSingleObject(pi1.hProcess,INFINITE);

printf("1st child complete\n");

WaitForSingleObject(pi2.hProcess,INFINITE);

printf("2nd child complete\n");

//close handles

CloseHandle(pi1.hProcess);

CloseHandle(pi1.hThread);

printf("\nProcess Main ended...\n");

return 0;

}

References:

- Galvin

- MSDN

Joydip Datta
1/27/2007 4:41:36 PM

No comments: