你可能需要一个fork()的疯狂练习

一、啥叫fork

百度翻译的解释是 

餐叉; 叉(挖掘用的园艺工具); (道路、河流等的) 分岔处,分流处,岔口,岔路;

而在Linux系统里 fork()函数是一个比较好玩的东西。

fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。

二、使用

我们可以看一个简单的例子

以下所有的程序的测试环境

系统:deepin 15.11

这个系统大概长这个样子

void fork0() 
{   pid_t fpid;
    fpid=fork();
    if (fpid == 0) {
	printf("Hello from child\n");
    }
    else {
	printf("Hello from parent\n");
    }
}

调用后的运行结果:

Hello from parent
Hello from child

两条输出 parent表示父进程,child表示子进程。

为什么嘞 

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值;

这个程序执行的时候  父进程和子进程的代码都为fork之后的代码

但因为fork()返回的值不同 所以打印了不同的语句。

三、开始疯狂练习

1.

void fork1()
{
    int x = 1;
    pid_t pid = fork();

    if (pid == 0) {
	printf("Child has x = %d\n", ++x);
    } 
    else {
	printf("Parent has x = %d\n", --x);
    }
    printf("Bye from process %d with x = %d\n", getpid(), x);
}

输出结果:

Parent has x = 0
Bye from process 21410 with x = 0
Child has x = 2
Bye from process 21411 with x = 2

2.

void fork2()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("Bye\n");
}

输出结果

L0
L1
L1
Bye
Bye
Bye
Bye

3.

void fork3()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("L2\n");    
    fork();
    printf("Bye\n");
}

输出结果

L0               
L1
L1
L2
L2
L2
Bye
L2
Bye
Bye
Bye
Bye
Bye
Bye
Bye

4.

void fork4()
{
    printf("L0\n");
    if (fork() != 0) {
	printf("L1\n");    
	if (fork() != 0) {
	    printf("L2\n");
	}
    }
    printf("Bye\n");
}

输出结果:

L0
L1
Bye
L2
Bye
Bye

5.

void fork5()
{
    printf("L0\n");
    if (fork() == 0) {
	printf("L1\n");    
	if (fork() == 0) {
	    printf("L2\n");
	}
    }
    printf("Bye\n");
}

输出结果:

L0
Bye
L1
Bye
L2
Bye

 

6.

void cleanup(void) {
    printf("Cleaning up\n");
}

void fork6()
{
    atexit(cleanup);
    fork();
    exit(0);
}

输出结果:

Cleaning up
Cleaning up

7.

void fork7()
{
    if (fork() == 0) {
	/* Child */
	printf("Terminating Child, PID = %d\n", getpid());
	exit(0);
    } else {
	printf("Running Parent, PID = %d\n", getpid());
	while (1)
	    ; /* Infinite loop */
    }
}

输出结果 


8.

void fork8()
{
    if (fork() == 0) {
	/* Child */
	printf("Running Child, PID = %d\n",
	       getpid());
	while (1)
	    ; /* Infinite loop */
    } else {
	printf("Terminating Parent, PID = %d\n",
	       getpid());
	exit(0);
    }
}

输出结果: 


 

9.

void fork9()
{
    int child_status;

    if (fork() == 0) {
	printf("HC: hello from child\n");
        exit(0);
    } else {
	printf("HP: hello from parent\n");
	wait(&child_status);
	printf("CT: child has terminated\n");
    }
    printf("Bye\n");
}

输出结果:

HP: hello from parent
HC: hello from child
CT: child has terminated
Bye

10.

#define N 5
void fork10()
{
    pid_t pid[N];
    int i, child_status;

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    exit(100+i); /* Child */
	}
    for (i = 0; i < N; i++) { /* Parent */
	pid_t wpid = wait(&child_status);
	if (WIFEXITED(child_status))
	    printf("Child %d terminated with exit status %d\n",
		   wpid, WEXITSTATUS(child_status));
	else
	    printf("Child %d terminate abnormally\n", wpid);
    }
}

输出结果:

Child 25972 terminated with exit status 100
Child 25973 terminated with exit status 101
Child 25974 terminated with exit status 102
Child 25975 terminated with exit status 103
Child 25976 terminated with exit status 104

11.

#define N 5
void fork11()
{
    pid_t pid[N];
    int i;
    int child_status;

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0)
	    exit(100+i); /* Child */
    for (i = N-1; i >= 0; i--) {
	pid_t wpid = waitpid(pid[i], &child_status, 0);
	if (WIFEXITED(child_status))
	    printf("Child %d terminated with exit status %d\n",
		   wpid, WEXITSTATUS(child_status));
	else
	    printf("Child %d terminate abnormally\n", wpid);
    }
}

输出结果:

Child 25999 terminated with exit status 104
Child 25998 terminated with exit status 103
Child 25997 terminated with exit status 102
Child 25996 terminated with exit status 101
Child 25995 terminated with exit status 100

12.

#define N 5
void fork12()
{
    pid_t pid[N];
    int i;
    int child_status;

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    /* Child: Infinite Loop */
	    while(1)
		;
	}
    for (i = 0; i < N; i++) {
	printf("Killing process %d\n", pid[i]);
	kill(pid[i], SIGINT);
    }

    for (i = 0; i < N; i++) {
	pid_t wpid = wait(&child_status);
	if (WIFEXITED(child_status))
	    printf("Child %d terminated with exit status %d\n",
		   wpid, WEXITSTATUS(child_status));
	else
        //异常终止
	    printf("Child %d terminated abnormally\n", wpid);
    }
}

输出结果:

Killing process 26023
Killing process 26024
Killing process 26025
Killing process 26026
Killing process 26027
Child 26023 terminated abnormally
Child 26024 terminated abnormally
Child 26025 terminated abnormally
Child 26026 terminated abnormally
Child 26027 terminated abnormally

13.

void int_handler(int sig)
{
    printf("Process %d received signal %d\n", getpid(), sig); /* Unsafe */
    exit(0);
}

/*
 * fork13 - Simple signal handler example
 */
#define N 5
void fork13()
{
    pid_t pid[N];
    int i;
    int child_status;

    signal(SIGINT, int_handler);
    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    /* Child: Infinite Loop */
	    while(1)
		;
	}

    for (i = 0; i < N; i++) {
	printf("Killing process %d\n", pid[i]);
	kill(pid[i], SIGINT);
    }

    for (i = 0; i < N; i++) {
	pid_t wpid = wait(&child_status);
	if (WIFEXITED(child_status))
	    printf("Child %d terminated with exit status %d\n",
		   wpid, WEXITSTATUS(child_status));
	else
	    printf("Child %d terminated abnormally\n", wpid);
    }
}

输出结果:

Killing process 26105
Killing process 26106
Killing process 26107
Killing process 26108
Killing process 26109
Process 26105 received signal 2
Process 26106 received signal 2
Process 26109 received signal 2
Process 26108 received signal 2
Process 26107 received signal 2
Child 26105 terminated with exit status 0
Child 26106 terminated with exit status 0
Child 26107 terminated with exit status 0
Child 26108 terminated with exit status 0
Child 26109 terminated with exit status 0

 

14.

int ccount = 0;
void child_handler(int sig)
{
    int child_status;
    pid_t pid = wait(&child_status);
    ccount--;
    printf("Received SIGCHLD signal %d for process %d\n", sig, pid); /* Unsafe */
    fflush(stdout); /* Unsafe */
}

/*
 * fork14 - Signal funkiness: Pending signals are not queued
 */
#define N 5
void fork14()
{
    pid_t pid[N];
    int i;
    ccount = N;
    signal(SIGCHLD, child_handler);

    for (i = 0; i < N; i++) {
	if ((pid[i] = fork()) == 0) {
	    sleep(1);
	    exit(0);  /* Child: Exit */
	}
    }
    while (ccount > 0)
	;
}

输出结果:

Received SIGCHLD signal 17 for process 7293
Received SIGCHLD signal 17 for process 7294
Received SIGCHLD signal 17 for process 7295
Received SIGCHLD signal 17 for process 7296
Received SIGCHLD signal 17 for process 7297

有时候卡住

15.

void child_handler2(int sig)
{
    int child_status;
    pid_t pid;
    while ((pid = wait(&child_status)) > 0) {
	ccount--;
	printf("Received signal %d from process %d\n", sig, pid); /* Unsafe */
	fflush(stdout); /* Unsafe */
    }
}

/*
 * fork15 - Using a handler that reaps multiple children
 */
#define N 5
void fork15()
{
    pid_t pid[N];
    int i;
    ccount = N;

    signal(SIGCHLD, child_handler2);

    for (i = 0; i < N; i++)
	if ((pid[i] = fork()) == 0) {
	    sleep(1);
	    exit(0); /* Child: Exit */

	}
    while (ccount > 0) {
	pause();
    }
}

 

输出结果:

Received signal 17 from process 26330
Received signal 17 from process 26331
Received signal 17 from process 26332
Received signal 17 from process 26333
Received signal 17 from process 26334

16.

void fork16() 
{
    if (fork() == 0) {
	printf("Child1: pid=%d pgrp=%d\n",
	       getpid(), getpgrp());
	if (fork() == 0)
	    printf("Child2: pid=%d pgrp=%d\n",
		   getpid(), getpgrp());
	while(1);
    }
} 

输出结果:

17.

void fork17() 
{
    if (fork() == 0) {
	printf("Child: pid=%d pgrp=%d\n",
	       getpid(), getpgrp());
    }
    else {
	printf("Parent: pid=%d pgrp=%d\n",
	       getpid(), getpgrp());
    }
    while(1);
} 

输出结果:


 

发布了19 篇原创文章 · 获赞 23 · 访问量 6821

猜你喜欢

转载自blog.csdn.net/qq_43176366/article/details/102923906