Linux高级编程--06.进程概述
进程控制块
在Linux中,每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,它通常包含如下信息:
- 进程id。系统中每个进程有唯一的id,在C语言中用pid_t类型表示,其实就是一个非负整数。
- 进程的状态,有运行、挂起、停止、僵尸等状态。
- 进程切换时需要保存和恢复的一些CPU寄存器。
- 描述虚拟地址空间的信息。
- 描述控制终端的信息。
- 当前工作目录(Current Working Directory)。
- umask掩码。
- 文件描述符表,包含很多指向file结构体的指针。
- 和信号相关的信息。
- 用户id和组id。
- 控制终端、Session和进程组。
- 进程可以使用的资源上限(Resource Limit)。
fork和exec
fork的作用是根据一个现有的进程复制出一个新进程,原来的进程称为父进程(Parent Process),新进程称为子进程(Child Process)。
系统中同时运行着很多进程,这些进程都是从最初只有一个进程开始一个一个复制出来的。在Shell下输入命令可以运行一个程序,是因为Shell进程在读取用户输入的命令之后会调用fork复制出一个新的Shell进程,然后新的Shell进程调用exec执行新的程序。
一个程序可以多次加载到内存,成为同时运行的多个进程,例如可以同时开多个终端窗口运行/bin/bash,另一方面,一个进程在调用exec前后也可以分别执行两个不同的程序,例如在Shell提示符下输入命令ls,首先fork创建子进程,这时子进程仍在执行/bin/bash程序,然后子进程调用exec执行新的程序/bin/ls,如下图所示。
fork函数
fork函数的声明如下:
pid_t fork(void);
当fork复制进程失败时,会返回-1;当复制进程成功时,由于复制出来的进程只执行fork函数之后的代码。虽然父进程和子进程都会执行后续的代码,但可以通过fork的返回值加以区分,一个简单的示例如下:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
char *message;
int n;
pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
}
if (pid == 0) {
message = "This is the child\n";
n = 6;
} else {
message = "This is the parent\n";
n = 3;
}
for(; n > 0; n--) {
printf(message);
sleep(1);
}
return 0;
}
fork对父进程返回子进程的ID,对子进程返回0,因此可以通过返回值来区分是父进程还是子进程。
这样设计是有道理的,虽然子进程无法通过返回值获取进程ID,但可以通过getpid函数得到自己的进程id,也可以调用getppid函数得到父进程的id。在父进程中用getpid可以得到自己的进程id,然而要想得到子进程的id,只有将fork的返回值记录下来,别无它法。
根据返回值区分进程后,既可以指定他们的流程了,上例中他们的流程分别如下:
exec函数
用fork创建子进程后执行的是和父进程相同的程序,子进程也可以通过exec函数执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。功能上类似C的system函数。
一个示例如下:
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
perror("exec ps");
exit(1);
}
Linux高级编程--06.进程概述的更多相关文章
- Linux高级编程--08.线程概述
线程 有的时候,我们需要在一个基础中同时运行多个控制流程.例如:一个图形界面的下载软件,在处理下载任务的同时,还必须响应界面的对任务的停止,删除等控制操作.这个时候就需要用到线程来实现并发操作. 和信 ...
- linux高级编程基础系列:线程间通信
linux高级编程基础系列:线程间通信 转载:原文地址http://blog.163.com/jimking_2010/blog/static/1716015352013102510748824/ 线 ...
- Unix环境高级编程——守护进程记录总结(从基础到实现)
一.概念及其特征 守护进程是系统中生存期较长的一种进程,常常在系统引导装入时启动,在系统关闭时终止,没有控制终端,在后台运行.守护进程脱离于终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程 ...
- linux系统编程之进程(八):守护进程详解及创建,daemon()使用
一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而且提供某种服务,不是对整个 ...
- linux高级编程
系统调用 01.什么是系统调用? 02.Linux系统调用之I/O操作(文件操作) 03.文件描述符的复制:dup(), dup2() 多进程实现多任务 04.进程的介绍 05.Linux可执行文件结 ...
- linux系统编程之进程(六):父进程查询子进程的退出,wait,waitpid
本节目标: 僵进程 SIGCHLD wait waitpid 一,僵尸进程 当一个子进程先于父进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行,或者父进程调用了wait才告终止. ...
- Linux系统编程——特殊进程之僵尸进程
僵尸进程(Zombie Process) 进程已执行结束,但进程的占用的资源未被回收.这种进程称为僵尸进程. 在每一个进程退出的时候,内核释放该进程全部的资源.包含打开的文件.占用的内存等. 可是仍然 ...
- linux系统编程之进程(一)
今天起,开始学习linux系统编程中的另一个新的知识点----进程,在学习进程之前,有很多关于进程的概念需要了解,但是,概念是很枯燥的,也是让人很容易迷糊的,所以,先抛开这些抽象的概念,以实际编码来熟 ...
- linux c编程:进程控制(三)_exec函数
fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间.堆.栈等资源的副本.注意,子进程持有的是上述存储空间的“副本”,这意味着父子进 ...
随机推荐
- Hibernate入门5持久化对象关系和批量处理技术
Hibernate入门5持久化对象关系和批量处理技术 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv 前言: 前面学习了Hiberna ...
- PHP学习计划
- PHP实现微信公众账号开发
1.首先需要一个可以外网访问的接口url. 我这里是申请的新浪免费云服务器,http://xxxxx.applinzi.com/wx.php,具体自己可以去新浪云中心申请地址为:http://www. ...
- WIFI WPA1/2 Crack for Windows
0x00 前言 目前WIFI WPA破解主要 以“aircrack-ng”为代表,运行于Linux系统( 如Kali Linux ),Windows系统比较少见,主要是Windows系统下WIFI网卡 ...
- Python学习笔记(2):数据库访问
本来打算继续用Access的,但费了非常大的劲,还是没有搞定.回过头,发现使用sqlite,简单到令人发指.干脆,把C#的CommonCode往这边迁移,先把AccessDB搬过来再说. 类结构和C# ...
- Awesome C/C++
Awesome C/C++ A curated list of awesome C/C++ frameworks, libraries, resources, and shiny things. In ...
- APK重签名总结
keytool -genkey -alias aeo_android.keystore -keyalg RSA -validity 20000 -keystore aeo_android.keysto ...
- oreData的学习记录
1.如果想创建一个带有coreData的程序,要在项目初始化的时候勾选中 2.创建完成之后,会发现在AppDelegate里多出了几个属性,和2个方法 <span style="fon ...
- linux下IM server搭建
一步一步开始做. 附录: 一套开源协议:http://www.igniterealtime.org/index.jsp Proso:http://prosody.im/ 那谁网友的笔记http://w ...
- [界面开发新秀]免费的AYUI,开发360领航版系列教程[2/40]
<界面开发风AYUI-基于WPF By AY> 大家好! 距离上篇博客发布有10天了,因为我在开发AYUI4.X效果更惊艳 我是AY,很高兴,终于可以写自己的作品的,网络博 ...