APUE读书笔记:进程控制

重点函数:fork,exit,_exit

一、fork

函数原型:

#include <unistd.>

pid_t fork(void)

函数说明:fork函数将创建一个子进程,该函数调用一次,但是有两次返回。子进程返回值为0,父进程的返回值是该子进程的进程ID。

小技巧:父进程能够拿到该次fork生成的子进程的ID,这是唯一的机会。而子进程不需要关心自己的进程ID。通过是否关心子进程id,就能明确地区分是父进程还是子进程。

相关的函数:

获取自己的进程ID:getpid()

获取父进程ID:getppid()


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{
pid_t pid;

if ((pid = fork()) < 0) {
exit(-1);
} else if (pid == 0) {
printf("This is child. pid=%d, ppid=%d\n", getpid(), getppid()); //child
exit(0);
} else {
sleep(2);
printf("This is parent. pid=%d, ppid=%d\n", getpid(), getppid()); //parent
exit(0);
}
return 0;
}

fork后的父子进程会共享哪些资源?

会共享持有的所有文件句柄。更多详情查看APUE(unix环境高级编程)中文版的175页。

特别地,IO缓存区作为特殊的文件句柄,也是会被共享的。

fork常见的使用场景:

1,一个父进程希望复制自己,使父子进程同时执行不同的代码段。这在网络服务中是常见的,父进程等待客户端的服务请求,当请求到达时,父进程fork一个子进程,子进程负责对该次请求作出处理和响应,而父进程则等待下一次服务请求的到达。

2,一个进程要执行一个不同的程序。在shell中是常见的,子进程从fork返回后立即调用exec。

常见的shell执行流:

假如要执行这条命令:ls -la
./,shell会先fork一个子进程,该子进程负责对命令进行处理,子进程处理结束后告诉它的父进程(shell进程)说我处理完了,可执行下一次命令。

二、exit退出函数

摘自APUE,178页

进程有5种正常终止方式:

1,在main函数内调用return。这种方式类似于exit。

2,调用exit函数。该函数由ISO C定义,其操作包括调用各种只处理程序,然后关闭所有标准IO流等。因为ISO
C并不处理文件描述符,多进程以及作业控制,所以这一定义对于UNIX系统而言是不完整的。

3,调用_exit或者_Exit函数。ISO
C定义_Exit,其目的是为进程提供一种无需运行终止处理程序或心法处理程序而终止的方法。对标准IO流是否进行冲洗,取决于系统的实现。在UNIX中,_exit和_Exit是同义的,并不清洗IO缓存(这意味着如果使用_exit来终止程序的话,io缓存区的内容不会输出到屏幕,也不会输出到文件)。_exit由exit调用。

4,进程的最后一个线程在启动例程中执行返回语句。

5,进程的最后一个线程调用pthread_exit函数。

有3种异常终止方式:

1,调用abort函数。

2,当进程接收到某些信号时。

3,最后一个线程对取消(cancellaction)请求作出响应。

不管如何终止,最后都会执行内核中的同一段代码。这段代码为响应进程关闭所有打开描述符,释放它所使用的存储器等。

note:对于大多数unix系统而言,exit是标准C库的一个函数,_exit是一个系统调用(系统调用指的是内核提供的接口)。

时间: 2024-09-28 11:34:48

APUE读书笔记:进程控制的相关文章

APUE读书笔记:关于sigsuspend

sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型. int sigsuspend(const sigset_t *mask); 先忽略参数,sigsuspend完成的操作是阻塞进程的运行,直到有信号的产生.这样来看与另一个函数的作用相同.pause() 加上参数来理解,sigsuspend完成的操作是阻塞进程的运行,如果信号是mask参数设置的信号集,那么该信号是pending状态,而不会影响进程的阻塞状态,意思是进程仍然在阻塞中,直到不在信号集中的信号出现,进

apue读书笔记之apue.h的设置

apue读书笔记之apue.h的设置 学习apue时,程序都有一个共同的头文件apue.h.那么该如何设置呢?本文是apue版本为第三版. 首先去图书官方网址下载对应的源码tar包.地址为:http://www.apuebook.com/code3e.html 解压tar包. cp  apue.3e/include/apue.h  /usr/include cp  apue.3e/lib/error.c     /usr/include

linux c 笔记 进程控制(一)

1.进程简述 进程是一个动态的实体,操作系统资源分配的基本单位,每个进程都有一个非负整型的唯一进程 ID.因为进程 ID标识符总是唯一的,常将其用做其他标识符的一部分以保证其唯一性.    1)进程标识:    每个进程都有一个非负整型的唯一进程 ID.因为进程 ID标识符总是唯一的,常将其用做其他标识符的一部分以保证其唯一性.tmpnam 函数将进程 ID作为名字    的一部分创建一个唯一的路径名.    有某些专用的进程:进程 ID 0是调度进程,常常被称为交换进程 ( swapper )

linux c 笔记 进程控制(三)

进程退出    进程结束表示进程即将结束运行,在linux系统中进程的退出方法分为正常退出和异常退出两种.exit函数进程有三种正常终止法及两种异常终止法.(1) 正常终止:    (a) 在main函数内执行return语句.这等效于调用 exit.    (b) 调用exit函数.此函数由ANSI C定义,其操作包括调用各终止处理程序(终止处理程序在调用atexit函数时登录),然后关闭所有标准I/O流等.因为ANSI C并不处理文件描述符.多进程(父.子进程)以及作业控制,所以这一定义对

APUE读书笔记: 文件和目录

stat, fstat, fstatat 和 lstat函数: stat函数返回与pathname命名文件相关的信息结构: fstat函数返回已在文件描述符fd打开文件的相关信息: lstat函数与stat函数类似,但当命名文件是一个符号链接时,返回该符号链接的相关信息: fstatat函数为相对于当前打开目录(有fd参数指向)的路径名返回文件统计信息. struct stat 的具体定义如下图: 文件类型: 文件类型包括:普通文件,目录文件,块特殊文件,字符特殊文件,FIFO,套接字和符号链接

APUE读书笔记:File I/O

文件描述符: 进程通过文件描述符来操作文件,文件描述符可以通过open, openat, creat系统调用返回; shell和其他应用默认打开标准输入(STDIN_FILENO),标准输出(STDOUT_FILENO),标准错误(STDERR_FILENO)三个文件描述符. open和openat函数: 文件可以通过调用open或者openat函数打开或者创建: 新文件描述符使用最小未使用原则: TOCTTOU(time of check of time of use)的基本含义:程序是脆弱的

APUE读书笔记-第四章 文件和目录

到第四章了,不知什么时候才能把这本书看完,耽误的时间太多了. 第四章是在第三章的基础上,主要描述文件系统的其他性质和文件的性质. 4.2 stat.fstat.fstatat.lstat函数 首先来看看这四个函数的原型: #include <sys/stat.h> ///usr/include/x86_64-linux-gnu/sys/ int stat (const char *__restrict __file, struct stat *__restrict __buf) int fst

apue读书笔记-第14章 高级IO

多路I/O转接 与select函数不同,poll不是为每个状态(可读性.可写性和异常状态)构造一个描述符集,而是构造一个pollfd结构数组,每个数组元素指定一个描述符编号以及其所关心的状态 readv和writev函数 作用:在一次函数调用中读.写多个非连续缓存区 总结:应当用尽量少的系统调用次数来完成任务.如果只写少量的数据,会发现自己复制数据然后使用一次write会比用writev更合算.但也可能发现,这样获得的性能提升并不值得,因为管理中间缓冲区会增加程序复杂度. readn和write

APUE读书笔记-第三章 文件I/O

今天看得挺快的,一下子就把第二章看完了,不过第二章也确实看得不仔细,这一章其实在程序设计中还是非常重要的,因为这一章的内容决定了程序的可移植性. 好了,回到这一章的主题文件I/O. 3.2节主要对文件描述符的概念进行了简单的介绍.根据APUE:文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符.我也简单地翻了一下LKD和<深入理解linux内核>,其中对于文件描述符的讲解不是很多,所以对于文件描述符也谈不出来太深入理解,各大家还是分享一篇blog吧.