Creating Processes in C

This brief tutorial will show you how to create processes and communicate with them. It is important to note that the following tutorial uses the C POSIX Library and does not apply to Windows unless you compile with Cygwin. Sometimes you may need a program that can do two or more things at the same time. This can be achieved by creating a new process with with the fork() function.

Header Files

The fork function is defined in the following header:

#include <unistd.h>

fork() returns a type called pid_t, which is defined in this header:

#include <sys/types.h>

A useful function while forking is the wait() function, defined in this header:

#include <sys/wait.h>

Fork

pid_t fork(void);

fork() creates a new process, called a child. The original process that created the child is called the parent. The child gets a separate copy of the variables the parent had. Fork takes no arguments and returns a pid_t type variable. fork() will return -1 for an error, 0 for the child process, and the child's pid for the parent process.

Wait

pid_t wait(int*);

wait() is a function that waits for the child to end. It takes an int pointer as the only argument. This int pointer is set to the exit status of child. wait() returns the pid of the child it is waiting for.

Fork and Wait Code Example

wait.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
 
int main(void) {
	pid_t pid;
	pid=fork(); /* Call the fork function */
 
	if (pid==-1) { /* fork call failed */
		printf("Failed to fork");
		return 1;
	}
 
	if (pid==0) { /* this is the child */
		printf("This is the child process\n");
		sleep(5); /* child pauses for 5 seconds */
	}
 
	if (pid>0) { /* this is the parent */
		wait(NULL); /* wait for the child process to end */
		printf("This is the parent process\n");
	}
	return 0;
}

Waitpid

pid_t waitpid(pid_t, int*, int);

waitpid() functions similarly to wait() except it lets you choose which child process to wait for. This is useful when you have multiple child process that are assigned different tasks. The first argument is the pid of the child you want to wait for. The second argument is an int pointer, which is set to the exit status of the child. The last argument is the option provided to waitpid(). It's common to set this argument to 0. waitpid() will return the pid of the child process, and -1 on error.

Waitpid Code Example

waitpid.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
 
int main(void) {
	/* These variables tell which 
	 * child is which */
	pid_t child1;
	pid_t child2;
	child1=fork();
	if (child1==-1) {
		perror("Failed to fork");
		return 1;
	}
	if (child1==0) { /* Child 1 pauses for 3 seconds */
		sleep(3);
		return 0;
	}
	child2=fork();
	if (child2==-1) {
		perror("Failed to fork");
		return 1;
	}
	if (child2==0) { /* Child 2 pauses for 6 seconds */
		sleep(6);
		return 0;
	}
	/* Parent waits for children */
	waitpid(child1, NULL, 0);
	printf("Child 1 is done!\n");
	waitpid(child2, NULL, 0);
	printf("Child 2 is done!\n");
	return 0;
}

Pipes

Pipes allow two processes to communicate with each other.

int pipe(int[2]);

Pipe returns 0 on success and -1 on failure. Pipe takes an int array the size of two as it's only argument. This array is turned into two Unix file descriptors. The first file descriptor at index 0 can only be read from, while the second file descriptor at index 1 is written to. You read and write to these file descriptors with the read() and write() functions. One process can write to one file descriptor, while the second process reads from the other.

Read and Write

int read(int, char*, int);
int write(int, char*, int);

Both functions return -1 on failure, otherwise they return the length of the data sent. Both functions take three arguments. The first int is the file descriptor that will be read/written. The second argument is the string that will be written. The third argument is the length of the string, including the '\0' character.

Fork and Pipe Code Example

pipe.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
 
int main(void) {
	pid_t pid;
	int pipe1[2]; /* the pipe file descriptor */
	if (pipe(pipe1)==-1) {
		printf("Failed to open pipe\n");
		return 1;
	}
	pid=fork(); /* fork processes */
	if (pid==-1) {
		printf("Error while forking\n");
		return 1;
	}
	if (pid==0) { /* child sends hello world message to parent */
		close(pipe1[0]); /* close the unused pipe */
		char buffer[]="Hello, World!\n";
		if (write(pipe1[1], buffer, strlen(buffer)+1)==-1) { /* sends hello world */
			return 1;
		}
	}
	if (pid>0) { /* parent recieves and prints message from child */
		close(pipe1[1]);
		char buffer[100];
		if (read(pipe1[0], buffer, 100)==-1) { /* recieves the sent string */
			return 1;
		}
		printf("%s", buffer);
	}
	return 0;
}
 
c/processes.txt · Last modified: 2010/07/13 02:00 by guest
 
Except where otherwise noted, content on this wiki is licensed under the following license:Public Domain
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki