Linux多任务编程——进程
进程编程常用函数
1--- fork
pitd_t fork(void);
创建一个新的子进程,其父进程为调用 fork() 函数的进程;
返回值:成功:子进程返回 0,父进程返回 子进程 PID;失败 返回 -1;
*1>新创建的子进程PID,与父进程PID不同;
*2>子进程 从 fork() 返回值开始运行,返回值为 0;父进程 fork() 返回新创建的子线程 PID
int main()
{
pid_t pid;
if ((pid = fork()) == -) {
perror("fork");
return ;
}
else if (pid == ) { //返回 0 代表子进程
printf("The return value is %d In child process! My PID is %d, My PPID is %d\n", pid, getpid(), getppid());
}
return ;
}
2--- exec函数族
exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。
与一般情况不同,exec函数族的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样,颇有些神似"三十六计"中的"金蝉脱壳"。看上去还是旧的躯壳,却已经注入了新的灵魂。只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。
可以使用 fork 创建一个子进程,在子进程中进行 exec 函数的调用 去完成某些比较危险的操作。使用时一定要注意这一点。
exec家族一共有六个函数,分别是:
(1)int execl(const char *path, const char *arg, ......);
(2)int execle(const char *path, const char *arg, ...... , char * const envp[]);
(3)int execv(const char *path, char *const argv[]);
(4)int execve(const char *filename, char *const argv[], char *const envp[]);
(5)int execvp(const char *file, char * const argv[]);
(6)int execlp(const char *file, const char *arg, ......);
其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。
#include <stdio.h>
#include <unistd.h> int main()
{
/*调用execlp函数,相当于调用了 “ps -ef”命令*/
if(execlp("ps", "ps", "-ef", NULL) < )
{
perror("ececlp error!");
}
return ;
}
它们之间的区别:
第一个区别是:
前四个取路径名做为参数,后两个取文件名做为参数,如果文件名中不包含 “/” 则从PATH环境变量中搜寻可执行文件, 如果找到了一个可执行文件,但是该文件不是连接编辑程序产生的可执行代码文件,则当做shell脚本处理。
第二个区别:
前两个和最后一个函数中都包括“ l ”这个字母 ,而另三个都包括“ v ”, " l "代表 list即表 ,而" v "代表 vector即矢量,也是是前三个函数的参数都是以list的形式给出的,但最后要加一个空指针,如果用常数0来表示空指针,则必须将它强行转换成字符指针,否则有可能出错。,而后三个都是以矢量的形式给出,即数组。
最后一个区别:
与向新程序传递环境变量有关,如第二个和第四个以e结尾的函数,可以向函数传递一个指向环境字符串指针数组的指针。即自个定义各个环境变量,而其它四个则使用进程中的环境变量。
3--- exit( ) 和 _exit( )
exit( )是标准库函数(Standard library)
_exit( ) 时系统调用函数(system call)
exit( ) 和 _exit( ) 都是用来终止进程的。当程序执行到 exit( )或 _exit( )时,进程会无条件地停止剩下的所有操作,清除各种数据结构,并终止本进程的运行。但是这连个函数还是有区别的:
4--- wait( ) 和 waitpid( )
wait( )函数用于父进程(也就是调用它的进程)阻塞,直到一个子进程结束,或者接到一个指定信号为止,如果父进程没有子进程或者其他进程的子进程已经结束,则wait( )会立即返回 -1;
waitpid( )的作用和wait( )一样,但并不一定等待第一个终止的子进程。waitpid( )有若干个选项,可以提供一个非阻塞版本的wait()功能。
函数原型:
pid_t wait(int *status); status 指向的整型对象用来保存进程结束时的状态。另外,子进程的结束状态可由linux中一些特定的宏来测定。
返回值 成功:已回收子进程的进程号。 失败: -1
pid_t waitpid(pid_t pid, int *status, int options);
pid: pid > 0: 回收进程 ID 为 pid 的子进程
pid = -1:回收任何一个子进程,此时和 wait()功能一样
pid = 0:回收其组 ID 等于调用进程的 ID 的任一子进程
pid < -1:回收其组 ID 等于 pid 的绝对值的任一子进程
status:同wait()
options:WNOHANG:若指定的子进程没有结束,则 waitpid()不阻塞而立即返回,此时返回值为 0
WUNRTACED:为了实现某种操作,由pid 指定的任一子进程已被暂停,但其状态自暂停依赖还未报告过,则返回其状态
返回值:>0:已结束运行的子进程的进程号
0:使用 WNOHANG 且没有子进程退出
-1:出错
5--- 守护进程
守护进程也就是通常所说的Daemon进程,他是 Linux 中的后台服务进程。 通常在系统启动时开始执行, 在系统关闭时终止。
编写守护进程的步骤(5步):
(1) 创建子进程,父进程退出。
1 if ( < pid = fork()) {
exit(); /*父进程退出*/
}
(2) 在子进程中创建新会话 (两个新的概念:进程组、会话期)
进程组:一个或多个进程的集合。有进程组由进程组 ID 来唯一标识。除了进程号(PID)之外,进程组 ID 也是一个进程的必备属性。
会话:会话是一个或多个进程组的集合。
pit_t setsid(void); 成功:返回该进程组 ID 出错:返回 -1
用于创建一个新的会话,并担任该会话组的组长。调用 setsid() 有下面三个作用。
① 让进程摆脱原会话的控制 ② 让进程摆脱原进程组的控制 ③ 让进程摆脱原控制终端的控制
(3) 改变当前目录
通常做法是让 “/” (根目录)作为守护进程的工作目录
(4) 重设文件权限掩码
umask(); 是设置文件权限掩码的函数,通常的使用方法是 umask(0);
(5) 关闭文件描述符
1 int num;
num = getdtablesize(); // 获取当前进程文件描述表大小
for (i = ; i < num; i++)
{
close(i);
}
Linux多任务编程——进程的更多相关文章
- Linux多任务编程之七:Linux守护进程及其基础实验(转)
来源:CSDN 作者:王文松 转自Linux公社 ------------------------------------------------------------------------- ...
- Linux多任务编程之六:编写多进程程序及其代码(转)
来源:CSDN 作者:王文松 转自Linux公社 ------------------------------------------------------------------------- ...
- Linux多任务编程之五:exit()和_exit()函数(转)
来源:CSDN 作者:王文松 转自:Linux公社 ----------------------------------------------------------------------- ...
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- Linux多任务编程之一:任务、进程、线程(转)
来源:CSDN 作者:王文松 转自:Linux公社 Linux下多任务介绍 首先,先简单的介绍一下什么叫多任务系统?任务.进程.线程分别是什么?它们之间的区别是什么?,从而可以宏观的了解一下这三者 ...
- linux系统编程-进程
进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...
- Linux系统编程@进程管理(一)
课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...
- [linux] C语言Linux系统编程进程基本概念
1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...
- Linux多任务编程——线程
线程基础 △ 由于进程的地址空间是私有的,因此在进行上下文切换时,系统开销比较大 △ 在同一个进程中创建的线程共享该进程的地址空间 △ 通常线程值得是共享相同地址空间的多个任务 △ 每个线程的私有这些 ...
随机推荐
- Java基础知识强化36:StringBuffer类之StringBuffer的概述
1. StringBuffer类概述: (1)String的缺陷: 我们如果对字符串进行拼接操作,每次拼接,都会构造一个新的String对象,既耗时,又浪费空间.如下图: (2)StringBuffe ...
- SVN服务器的本地搭建和使用
用VisualSVN server 服务端和 TortoiseSVN客户端搭配使用. 详细步骤如下 http://www.2cto.com/os/201412/361931.html
- 自定义控件 进度条 ProgressBar-2
使用 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bqt ...
- DataSet与DataTable的区别
DataSet:数据集.一般包含多个DataTable,用的时候,dataset["表名"]得到DataTable DataTable:数据表. 一: SqlDataAdapter ...
- iOS项目名称、版本号与屏幕分辨率
iOS的版本号,一个叫做Version,一个叫做Build,这两个值都可以在Xcode 中选中target,点击“Summary”后看到. Version在plist文件中的key是“CFBundle ...
- PHP扩展开发(2) - VS2013环境搭建
1. 安装VS2013 2. Cygwin安装 3. 下载Windows的PHP源码 4. 修改~/ext/ext_skel_win32.php 加上 $cygwin_path = 'c:\c ...
- 使用PHP对数据库输入进行恶意代码清除
这是一个有用的PHP函数清理了所有的输入数据,并删除代码注入的几率. function sanitize_input_data($input_data) { $input_data = trim(ht ...
- php 中_set()_get()实例解析
<?php class Person { // 下面是人的成员属性, 都是封装的私有成员 private $name; // 人的名子 private $sex; // 人的性别 private ...
- python学习第十八天 --错误&异常处理
这一章节主要讲解python的错误和异常处理 什么是错误和异常?及其区别? 错误: 1.语法错误:代码不符合解释器或者编译器语法. 2.逻辑错误:不完整或者不合法输入或者计算出现问题. 异常:执行 ...
- 国威电话机WS824(5D)-3型调试文档--可以转行啦
多了一万多搞的机器,花了我和同事们两三个晚上,最近还要打技术支持得到的经验... 可以转行作弱电啦啦~~~) 一,外线分组调试: 默认设置为所有内线端口可用1,2,13,14,15,16打出.(16个 ...