OSLab多进程
日期:2019/3/23
内容:Linux下与多进程相关的函数。
进程基本知识
- 定义
应用程序关于某数据集合上的一次运行活动。
- 特点
·操作系统进行资源分配和调度的基本单位
·进程是程序的一次执行过程。进程是动态的,程序是静态的。
·同一程序同时运行于若干个数据集合上,该程序将对应与若干个不同的进程。
·每个进程拥有独立的地址空间。地址空间包括代码段、数据段和堆栈段。
·进程之间的地址空间是隔离的。一个进程崩溃不会影响另一个进程,一个进程崩溃不会影响到操作系统。(一个程序开了多个进程,全局变量也不会共享)
fork函数
- 作用:创建一个子进程
- 返回值:
在父进程中,fork返回新创建子进程的进程PID;
在子进程中,fork返回0;
如果出现错误,fork返回一个负值;
- 实现细节
·OS为子进程创建一个PCB(Process Control Block, 进程控制块,其实质是一个结构体)
·复制代码和数据到子进程的地址空间(PID不复制)
- 获取PID
|
当前进程 |
获取子进程PID |
获取父进程PID |
|
子进程 |
getpid() |
getppid() |
|
父进程 |
pid=fork() |
getpid() |
获取PID代码样例
|
/************************************************************************* > File Name: testfork.c > Author: sinkinben > E-mail: sinkinben@qq.com > Created Time: Sat 23 Mar 2019 08:13:00 AM CST ************************************************************************/
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { //pid_t pid = fork(); pid_t pid; pid = fork(); //sleep(3); //3sec if (pid == 0) printf("In child process: child pid = %d, parent pid = %d\n", getpid(), getppid()); else printf("In parent process: parent pid = %d, child pid = %d\n", getpid(), pid); wait(NULL); return }
/* * 父进程先于子进程退出 * init是1号进程,接管子进程 * 所以in child process, getppid()总是返回1 * 解决办法:父进程调用sleep * 正解:调用wait,让父进程等待子进程结束 */
|
- 并发特性与隔离特性
|
并发 |
·二者并发运行,输出交织。 ·代码段相同:父进程从fork返回处执行(返回值为子进程PID);子进程从fork返回处执行(返回值0) |
|
隔离 |
·地址空间隔离,仅能访问自己的地址空间 ·出现非法访存,只影响当前进程 ·全局变量也不共享 |
并发和隔离样例代码
|
/************************************************************************* > File Name: concurrency.c > Author: sinkinben > E-mail: sinkinben@qq.com > Created Time: Sat 23 Mar 2019 08:38:19 AM CST ************************************************************************/
#include <stdio.h> #include <unistd.h> #include <stdlib.h> static void child() { int i = 0; for (i = 0; i < 5; i++) { puts("child"); printf("global = %d\n", global++); sleep(1); } } void parent() { int i = 0; for (i = 0; i < 5; i++) { puts("parent"); printf("global = %d\n", global++); sleep(1); } }
int main() { pid_t pid = fork(); if (pid) parent(); else child(); return }
|
运行结果

exec系列
名词解析:
exec:execute
l:list,表示参数是列表形式
v:vector,表示参数是数组形式
p:path,允许exec系列函数使用系统环境变量PATH下的路径
全家桶如下。
头文件:unistd.h
返回值:成功无返回值,失败-1.
|
函数 |
原型 |
描述 |
|
execl |
int execl(const char *path, const char *arg, ... |
·当前进程地址空间清空 ·将path指定的可执行程序的代码和数据装入当前地址空间 ·参数可变,最后一个必须NULL ·可以是相对/绝对路径 ·失败原因存于errno(一个Linux全局变量)中,可通过perror()打印。 ·execl成功的话,会执行另外的程序,因此成功无返回值。 ·参数格式:路径+程序名+参数1,2,3...,NULL |
|
execv |
int execv(const char *path, char *const argv[]); |
·argv数组最后一项必须为NULL ·argv[]={程序名,参数1,2,3...,NULL} ·参数格式:路径+argv |
|
execlp |
int execlp(const char *file, const char *arg, ... |
·允许使用PATH环境变量作为参数file |
|
execvp |
int execvp(const char *file, char *const argv[]); |
execl样例代码
|
/************************************************************************* > File Name: testexecl.c > Author: sinkinben > E-mail: sinkinben@qq.com > Created Time: Sat 23 Mar 2019 08:52:03 AM CST ************************************************************************/
#include <stdio.h> #include <unistd.h> int main() { puts("before execl"); int error_code = execl("/bin/echo", "echo", "sin", "cos", NULL); if (error_code < 0) perror("error execl"); puts("after execl"); return }
|
execv样例代码
|
/************************************************************************* > File Name: testexecv.c > Author: sinkinben > E-mail: sinkinben@qq.com > Created Time: Sat 23 Mar 2019 08:59:16 AM CST ************************************************************************/
#include <stdio.h> #include <unistd.h> int main() { puts("before execv(p)"); char *argv[] = { "ls", "-a", NULL}; //int error = execv("/bin/ls",argv); int error = execvp("ls", argv); if(error == -1) perror("error"); puts("after execv(p)"); return
}
|
exit
·头文件:stdlib.h
·原型:void exit(int status);
·功能
>>正常退出当前进程
>>将status & 0XFF作为退出码返回给父进程
·预定义常量
>>EXIT_SUCCESS, 为0,表示正常退出
>>EXIT_FAILURE,为非0,表示异常退出
>>在Linux shell中,$?可以获取程序的退出码
·main与exit
>>return 0 相当于exit(SUCCESS)
>>return !0 相当于exit(FAILURE)
>>start.asm(计算机组成原理知识:main返回的上一层是start.asm)
|
global _start extern main extern exit _start: call main add esp, push eax //作为参数eax->[ebp+8]传给exit call exit add esp, 4 hlt |
exit与$?代码实例
|
#include <stdio.h> #include <stdlib.h> int main() { exit(233); } |
运行结果

atexit
·头文件:stdlib.h
·原型:int atexit(void (*function)(void)); (参数是函数指针)
·功能
>>注册回调函数,进程正常结束时,function被调用
>>如果注册多个,以与注册相反的顺序调用
wait
·头文件:sys/types.h, sys/wait.h
·原型:pid_t wait(int *status);
·功能
>>等待子进程结束
>>如果status非空,子进程退出码保存在status
·退出码
进程可能由于不同原因退出。主动调用exit退出,或接收信号退出。
查询退出原因的宏
|
WIFEXITED(status) |
当子进程exit(0)时,为真。 |
|
WEXITSTATUS(status) |
当子进程exit(!0)时,返回退出码 |
|
WIFSIGNALED(status) |
当子进程接收信号后退出,为真 |
|
WTERMSIG(status) |
当子进程接收信号后退出,返回导致退出的信号码 |
OSLab多进程的更多相关文章
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- 取代SharedPreferences的多进程解决方案
Android的SharedPreferences用来存储一些键值对, 但是却不支持跨进程使用. 跨进程来用的话, 当然是放在数据库更可靠啦, 本文主要是给作者的新库PreferencesProvid ...
- python 多进程使用总结
python中的多进程主要使用到 multiprocessing 这个库.这个库在使用 multiprocessing.Manager().Queue时会出问题,建议大家升级到高版本python,如2 ...
- Nginx深入详解之多进程网络模型
一.进程模型 Nginx之所以为广大码农喜爱,除了其高性能外,还有其优雅的系统架构.与Memcached的经典多线程模型相比,Nginx是经典的多进程模型.Nginx启动后以daemon ...
- Python的多线程(threading)与多进程(multiprocessing )
进程:程序的一次执行(程序载入内存,系统分配资源运行).每个进程有自己的内存空间,数据栈等,进程之间可以进行通讯,但是不能共享信息. 线程:所有的线程运行在同一个进程中,共享相同的运行环境.每个独立的 ...
- 进击的Python【第十章】:Python的socket高级应用(多进程,协程与异步)
Python的socket高级应用(多进程,协程与异步)
- PHP的pcntl多进程
PHP使用PCNTL系列的函数也能做到多进程处理一个事务.比如我需要从数据库中获取80w条的数据,再做一系列后续的处理,这个时候,用单进程?你可以等到明年今天了...所以应该使用pcntl函数了. 假 ...
- 初探PHP多进程
h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h ...
- gdb进程调试,多进程调试
1.单进程的调试 常规的通过gdb cmd这种方式开启调试,特别说明的是通过attach的方法附加到一个指定的进程上去进行调试,这种方法适合于调试一个已经运行的进程,具体用法: gdb -p [pi ...
随机推荐
- Linux运维之shell脚本
一.bash漏洞 1)bash漏洞 bash漏洞是控制Linux计算机命令提示符的软件中存在的漏洞. bash是一个为GNU计划编写的Unix shell.它的名字是一系列缩写:Bourne-Agai ...
- *1LL在c++中的意义
LL其实代表long long,*1LL是为了在计算时,把int类型的变量转化为long long,然后再赋值给long long类型的变量 ANS=1LL*num*((1LL)*n*(n-1))/2 ...
- Java的GUI设计
这里笔者写一些自己做GUI时候的心得,希望可以帮助需要学习的同学,函数的实现和界面设计不在同一个文件中,且涉及参数的传递 一.继承于JFrame 当遇到继承于JFrame的类的时候,可以省去建立对 ...
- 前端之css操作2
一 伪类选择器 伪类选择器就是在查找的后面加上冒号和状态 hover:悬浮到上面就会变化一种状态 link:没有接触的状态 active:点击是触发的状态 visited:点击后的状态 <!DO ...
- 2018.11.04 洛谷P1081 开车旅行(倍增)
传送门 思路简单码量超凡? 感觉看完题大家应该都知道是倍增sbsbsb题了吧. 首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点. 然后利用刚刚预处理出的信息再预处理从每个点出发 ...
- Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)
https://codeforces.com/contest/1059/problem/E 题意 给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 ...
- Win7命令行编译cuda及设置Windows显卡响应时间
在开始菜单中找到Visual Studio 2013 >> Visual Studio Tools 选择86或64版本的VC命令提示符环境,我用的 VS2013 x86 Native To ...
- UVa 10828 Back to Kernighan-Ritchie (数学期望 + 高斯消元)
题意:给定一个 n 个结点的有向图,然后从 1 结点出发,从每个结点向每个后继结点的概率是相同的,当走到一个没有后继结点后,那么程序终止,然后问你经过每个结点的期望是次数是多少. 析:假设 i 结点的 ...
- embeded_2_separate_sync
//如果是8位的话,只选择低8位传输 //因为同步码也是可以自己设置,所以把同步码设置成parameter最好 module embeded_2_separate_sync( input clk, : ...
- AngularJS实战之ng-repeat的详细用法
一.基本语法 {{$index}}:获取元素的下标. {{$first}}:判断当前元素是否是第一个元素,是则为true,否则:false: {{$last}}:判断当前元素是否是最后一个元素,是则为 ...