`

linux c学习笔记----进程创建(fork,wait,waitpid)

阅读更多

1.pid_t fork();

(1)当一个进程调用了fork 以后,系统会创建一个子进程.这个子进程和父进程不同的地方只有他的进程ID 和父进程ID,其他的都是一样.就象符进程克隆(clone)自己一样.

(2)为了区分父进程和子进程,我们必须跟踪fork 的返回值. 当fork 掉用失败的时候(内存不足或者是用户的最大进程数已到)fork 返回-1,否则fork 的返回值有重要的作用.对于父进程fork 返回子进程的ID,而对于fork 子进程返回0.我

们就是根据这个返回值来区分父子进程的.

(3)一旦子进程被创建,父子进程一起从fork 处继续执行,相互竞争系统的资源.有时候我们希望子进程继续执行,而父进程阻塞直

到子进程完成任务.这个时候我们可以调用wait 或者waitpid 系统调用.

 

vfork(建立一个新的进程)


相关函数
wait,execve
表头文件
#include<unistd.h>
定义函数
pid_t vfork(void);
函数说明
vfork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。Linux 使用copy-on-write(COW)技术,只有当其中一进程试图修改欲复制的空间时才会做真正的复制动作,由于这些继承的信息是复制而来,并非指相同的内存空间,因此子进程对这些变量的修改和父进程并不会同步。此外,子进程不会继承父进程的文件锁定和未处理的信号。注意,Linux不保证子进程会比父进程先执行或晚执行,因此编写程序时要留意
死锁或竞争条件的发生。

返回值
如果vfork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。如果vfork 失败则直接返回-1,失败原因存于errno中。
错误代码
EAGAIN 内存不足。ENOMEM 内存不足,无法配置核心所需的数据结构空间。
范例
#include<unistd.h>
main()
{
if(vfork() = =0)
{
printf(“This is the child process\n”);
}else{
printf(“This is the parent process\n”);
}
}
执行
this is the parent process
this is the child process

 


wait(等待子进程中断或结束)
表头文件
#include<sys/types.h>
#include<sys/wait.h>
定义函数
pid_t wait (int * status);
函数说明
wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status 返回,而子进程的进程识别码也会一快返回。如果不在意结束状态值,则
参数
status可以设成NULL。子进程的结束状态值请参考waitpid()。
返回值
如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。

 

waitpid(等待子进程中断或结束)


表头文件
#include<sys/types.h>
#include<sys/wait.h>
定义函数
pid_t waitpid(pid_t pid,int * status,int options);
函数说明
waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status返回,而子进程的进程识别码也会一快返回。如果不在意结束状态值,则参数status可以设成NULL。参数pid为欲等待的子进程识别码,其他数值意义如下:
pid<-1 等待进程组识别码为pid绝对值的任何子进程。
pid=-1 等待任何子进程,相当于wait()。
pid=0 等待进程组识别码与目前进程相同的任何子进程。
pid>0 等待任何子进程识别码为pid的子进程。
参数option可以为0 或下面的OR 组合
WNOHANG 如果没有任何已经结束的子进程则马上返回,不予以等待。
WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。
子进程的结束状态返回后存于status,底下有几个宏可判别结束情况
WIFEXITED(status)如果子进程正常结束则为非0值。
WEXITSTATUS(status)取得子进程exit()返回的结束代码,一般会先用WIFEXITED 来判断是否正常结束才能使用此宏。
WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真
WTERMSIG(status)取得子进程因信号而中止的信号代码,一般会先用WIFSIGNALED 来判断后才使用此宏。
WIFSTOPPED(status)如果子进程处于暂停执行情况则此宏值为真。一般只有使用WUNTRACED 时才会有此情况。
WSTOPSIG(status)取得引发子进程暂停的信号代码,一般会先用WIFSTOPPED 来判断后才使用此宏。
返回值
如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。

 




例子:#include <unistd.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>

int main(void) {
    pid_t child,child2;
    int status;
    printf("This will demostrate how to get child status\n");
    if ((child = fork()) == -1) {
        printf("Fork Error :%s\n", strerror(errno));
        exit(1);
    } else if (child == 0) {
        child2 = fork();
        if(child2 == 0)
            printf("I am the child2:%ld\n",getpid());
        int i;
        printf("I am the child:%ld\n", getpid());
        for (i = 0; i < 1000000; i++) sin(i);
        i = 5;
        printf("I exit with %d\n", i);
        exit(i);
    }
    while (((child = waitpid(getpid(),&status,0)) == -1)&(errno == EINTR));
    if (child == -1)
        printf("Wait Error:%s\n", strerror(errno));
    else if (!status)
        printf("Child %ld terminated normally return status is zero\n",
            child);
    else if (WIFEXITED(status))
        printf("Child %ld terminated normally return status is %d\n",
            child, WEXITSTATUS(status));
    else if (WIFSIGNALED(status));
    printf("Child %ld terminated due to signal %d znot caught\n",
            child, WTERMSIG(status));
    getchar();
    return (EXIT_SUCCESS);
}

 

 

分享到:
评论

相关推荐

    Linux下C语言编程--进程的创建

    ### Linux下C语言编程——进程的创建 #### 一、进程的概念 在现代操作系统中,程序与进程是两个重要的概念。程序是指一个包含了可执行代码的文件,它本身是静态的,而进程则是指已经开始执行但尚未结束的程序实例...

    Linux进程控制编程-waitpid函数实例.pdf

    首先,通过`fork()`创建了一个子进程,然后父进程使用`waitpid`在循环中不断检查子进程是否已经结束。如果`waitpid`返回0,表示子进程仍在运行,父进程会打印一条消息并休眠1秒后再次尝试。如果`waitpid`返回了子...

    Linux进程控制编程-fork子进程创建实例.pdf

    在Linux操作系统中,进程是程序执行的一个实例,而`fork()`函数是用于创建新进程的关键系统调用。本文将深入探讨`fork()`函数的工作原理、使用方法及其在Linux进程控制编程中的重要性。 `fork()`函数是C语言标准库...

    Linux系统下C语言编程--进程的创建

    此外,C语言编程中还有其他与进程控制相关的系统调用,例如`exec()`系列函数用于替换进程的执行映像,`wait()`和`waitpid()`用于父进程等待子进程结束并回收资源,以及`signal()`和`sigaction()`处理进程中的信号。...

    eclipse-collections-forkjoin-7.1.2-API文档-中文版.zip

    赠送jar包:eclipse-collections-forkjoin-7.1.2.jar; 赠送原API文档:eclipse-collections-forkjoin-7.1.2-javadoc.jar; 赠送源代码:eclipse-collections-forkjoin-7.1.2-sources.jar; 赠送Maven依赖信息文件:...

    linux 进程 线程 fork 的深入思考

    本篇文章将基于一道经典的面试题目来探讨 Linux 下进程创建机制,特别是 `fork` 函数的工作原理。该题目不仅考验应试者对进程创建的理解,还涉及了对进程间关系的认识。 #### 题目描述 假设有一段 C 语言程序,在 ...

    linux-c-api-ref.zip_linux api_linux-c-api-ref

    3. **进程管理**:`fork()`创建新进程,`wait()`和`waitpid()`用于等待子进程结束,`exit()`和 `_exit()`终止进程。`exec()`系列函数(如`execl()`, `execv()`, `execle()`, `execvp()`等)用于替换当前进程的执行...

    linux下C语言开发笔记整理

    Unix/Linux提供了丰富的进程管理工具和系统调用,如`fork`用于创建新进程,`exec`系列用于执行新程序,`wait`和`signal`用于进程间通信。 ### Unix/Linux系统的信号处理 信号是Unix/Linux系统中一种用于进程间通信...

    fork创建多个子进程

    fork 创建多个子进程 在操作系统中,fork 是一个非常重要的系统调用,它可以创建一个新的子进程。fork 创建多个子进程是指通过 fork 系统调用创建多个子进程,每个子进程可以执行不同的任务。下面我们将讨论三种...

    linux系统fork创建子进程.zip

    在文件名列表中提到的"linux系统fork创建子进程"可能包含了一系列的源代码文件和对应的解释文档,通过这些文件,你可以逐步学习如何编写和调试使用`fork()`的程序,以及观察不同进程间的交互。这些实验可能涉及创建...

    进程创建函数fork()的基础实验

    进程创建函数fork()的基础实验,具体看博客http://blog.csdn.net/mybelief321/article/details/9046955

    linux-c.zip_C语言_Linux C语言_linux_linux-c

    常见的系统调用包括:`fork`用于创建进程,`exec`系列用于执行新程序,`wait`和`waitpid`用于等待子进程结束,`open`、`close`、`read`和`write`用于文件操作,以及`pipe`和`socket`用于进程间通信。理解并熟练运用...

    linux waitpid检测子进程是否退出

    在Linux操作系统中,`fork()`函数是创建子进程的关键,它允许一个进程(父进程)复制自身,生成一个新的进程(子进程)。这个过程是通过复制父进程的内存空间、文件描述符、信号处理函数等实现的。而`waitpid()`函数...

    mongodb linux 32位安装包 mongodb-linux-i686-3.0.5

    tar -zxvf mongodb-linux-i686-3.0.5.tgz -C /usr/local/ ``` 2. **创建数据目录**:MongoDB需要一个数据存储位置,通常命名为 `data/db`。可以在 `/var/lib/mongodb` 或自定义的位置创建。 ``` mkdir -p /var/...

    Linux下C语言应用编程-作者-杨铸-配套ppt-源代码-教学大纲

    PPT部分,包括了“13-多进程编程.ppt”、“14-进程间通信.ppt”、“16-网络编程.ppt”、“11-Linux下C语言编程环境.ppt”、“12-文件IO编程.ppt”和“15-多线程编程初步.ppt”。这些PPT是课堂讲解的核心,涵盖了多个...

    linux 多进程编程 fork

    linux 多进程编程 forklinux 多进程编程 forklinux 多进程编程 forklinux 多进程编程 forklinux 多进程编程 forklinux 多进程编程 forklinux 多进程编程 forklinux 多进程编程 forklinux 多进程编程 forklinux 多...

    linux实验报告\操作系统进程创建父子进程实验报告.docx

    实验的主要目标是熟悉Linux系统调用,并学习如何在Linux中创建进程。具体来说,实验要求通过父进程创建一个子进程,然后父子进程分别循环输出特定的字符串各5次,每次输出后延时10秒再进入下一次循环。 #### 关键...

    linux进程之fork创建新进程.zip

    在Linux操作系统中,`fork()`函数是创建新进程的关键接口,它是C语言标准库中的一个系统调用。这个过程被称为进程复制或者 fork。本压缩包包含的`fork.c`源代码文件很可能展示了如何使用`fork()`函数来创建一个新的...

    Linux下C语言应用编程--随书源代码

    4. **进程与线程**:Linux是一个多任务操作系统,C语言提供了系统调用(如fork、exec系列、waitpid)来创建和管理进程。同时,线程(pthread库)的使用可以让程序实现并行执行,提高效率。 5. **信号处理**:信号是...

Global site tag (gtag.js) - Google Analytics