linux进程控制编程
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
exec 函数
2. 函数原型
有六种不同的 exec函数可供使用,它们常常被统称为 exec函数。 #include <unistd.h> int execl(const char *pathname, const char *arg0 , ... /* (char *) 0 */); int execv(const char *pathname, char *const argv [] ); int execle(const char *pathname, const char *arg0, .../* (char *)0, char *const envp [] */); int execve(const char *pathname, char *const argv [], char *const envp [] ); int execlp(const char *filename, const char *arg0, ... /* (char *) 0 */); int execvp(const char *filename, char *const argv [] );
waitpid函数
3.程序举例
#include <sys/types.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { pid_t pid; if ((pid = fork()) < 0) printf("fork error\n"); else if (pid == 0) { printf("child, pid = %d\n", getpid()); sleep(5); } else { waitpid(pid, NULL, 0); printf("parent, pid = %d\n", getpid()); } printf("hello\n"); }
fork函数
fork有两种用法: (1) 一个父进程希望复制自己,使父、子进程同时执行不 同的代码段。这在网络服务进程中是常见的——父进 程等待委托者的服务请求。当这种请求到达时,父进 程调用 fork,使子进 程处理此请求。父进程则继续等 待下一个服务请求。 (2) 一个进程要执行一个不同的程序。这对 shell是常见的 情况。在这种情况下,子进程在从fork返回后立即调 用 exec.
子进程结束状态值。 3.如果有错误发生则返回(如果它没有任何子进程)。
waitpid函数
2.函数原型
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int st*atloc); pid_t waitpid(pid_ptid, int *statloc, int options); 两个函数返回:若成功则为进程 ID,若出错则为- 1 在一个子进程终止前, wait 使其调用者阻塞,而 waitpid 有 一选择项,可使调用者不阻塞。 如果一个子进程已经终止,是一个僵死进程,则 wait立即返 回并取得该子进程的状态,否则wait使其调用者阻塞直到一 个子进程终止。如调用者阻塞而且它有多个子进程,则在其 一个 子进程终止时, wait就立即返回。因为 wait返回终止子 进程的进程 ID,所以它总能了解是哪一 个子进程终止了。
vfork 函数
2. 示例程序
#include <stdlib.h> #include <stdio.h> #include <sys/types.h> int main(int argc, char *argv[]) { pid_t pid; if ((pid = vfork()) < 0) printf("fork error\n"); else if (pid == 0) { printf("child, pid = %d\n", getpid()); sleep(5); exit(1); } else { printf("parent, pid = %d\n", getpid()); }
第十讲
进程控制
LOGO
www.themegallery.com
LINUX
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数
State 进程在执行过程中会根据环境来改变state。Linux进程有以下状态:
R (TASK_RUNNING),可执行状态
fork函数
2. 示例程序
#include <sys/types.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char *argv[]) { pid_t pid; if ((pid = fork()) < 0) printf("fork error\n"); else if (pid == 0) { printf("child, pid = %d\n", getpid()); sleep(5); } else { printf("parent, pid = %d\n", getpid()); } printf("hello\n"); }
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数
exec 函数
1. exec 函数
上一节曾提及用vfork函数创建子进程后,子进程往往要调用一 种exec函数以执行另一个程序。 当进程调用一种exec函数时,该进程完全由新程序代换,而新 程序则从其 main函数开始执行。 因为调用exec并不创建新进程,所以前后的进程ID并未改变。 exec只是用另一个新程序替换了 当前进程的正文、数据、堆 和栈段。
T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。
向进程发送一个SIGSTOP信号,它就会因响应该信号而进入 TASK_STOPPED状态(除非该进程本身处于 TASK_UNINTERRUPTIBLE状态而不响应信号)。(SIGSTOP与SIGKILL 信号一样,是非常强制的。不允许用户进程通过 signal系列的系统调用 重新设置对应的信号处理函数。) 向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢 复到TASK_RUNNING状态。
Fra Baidu bibliotek
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数
fork函数
1. fork函数
一个现存进程调用 fork函数是 linux内核创建一个新进程的方法。 #include <sys/types.h> #include <unistd.h> pid_t fork(void); 返回:子进程中为0,父进程中为子进程ID,出错为-1 由fork创建的新进程被称为子进程( child process )。该函数被调 用一次,但返回两次。两次返回的区别是: 子进程的返回值是 0, 父进程的返回值则是新子进程的进程 ID。 一般来说,在 fork之后是父进程先执行还是子进程先执行是 不确定的。这取决于内核所使用的 调度算法。如果要求父、子进 程之间相互同步,则要求某种形式的进程间通信。
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数
vfork 函数
1. vfork 函数
vfork和fork之间的另一个区别是: vfork保证子进程先运 行,在它调用 exec或exit之后父进 程才可能被调度运行。 vfork用于创建一个新进程,而该新进程的目的是 exec一个新程 序。linux的 shell基本部分就是这种类型程序的一个例子。 vfork与fork一样都创建一个子进程, 但是它并不将父进程的地 址空间完全复制到子进程中,因为子进程会立即调用 exec(或 exit),于是也就不会存访该地址空间。不过在子进程调用 exec 或exit之前,它在父进程的空间中运行。 常用于uclinux
进程标识
3.其它标识符
除了进程ID,每个进程还有一些其他标识符。下列函数返回这些 标识符。 #include <sys/types.h> #include <unistd.h> pid_t getpid(void); 返回:调用进程的进程 ID pid_t getppid(void); 返回:调用进程的父进程 ID uid_t getuid(void); 返回:调用进程的实际用户 ID uid_t geteuid(void); 返回:调用进程的有效用户 ID gid_t getgid(void); 返回:调用进程的实际组 ID gid_t getegid(void); 返回:调用进程的有效组 ID
printf("hello\n");
}
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数
waitpid函数
1. wait 和waitpid函数
如果子进程在父进程之前终止,那么父进程又如何能在 做相应检查时得到子进程的终止状态呢? 内核为每个终止子进程保存了一定量的信息,所以当终止 进程的父进程调用 wait或waitpid 时,可以得到有关信 息。这种信息至少包括进程 ID、该进程的终止状态、以 反该进程使用的 CPU时间总量。内核可以释放终止进程 所使 用的所有存储器,关闭其所有打开文件。 调用wait或waitpid的进程可能会: 1.暂时停止目前进程的执行,直到有信号来到或子进程结束。 2如果在调用 wait()时子进程已经结束,则 wait()会立即返回
进程标识
1.引言 本章介绍 UNIX的进程控制,包括: 创建新进程 执行程序 进程终止
进程标识
2.进程标识
每个进程都有一个非负整型的唯一进程 ID。因为进程 ID 标识符总是唯一的,常将其用做其 他标识符的一部分以保证 其唯一性。 专用的进程: 进程 ID0 是调度进程,常常被称为交换进程 (swapper)。该 进程并不执行任何磁盘上的程序—它是内核的一部分,因此 也被称为系统进程。 进程 ID1 通常是init进程,在自举过程结束时由内核调用。 示例: ps –aux 显示其他用户启动的进程(a) 查看系统中属于自己的进程(x) 启动这个进程的用户和它启动的时间(u)
Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。
进程在退出的过程中,处于TASK_DEAD状态。 在这个退出过程中,进程占有的所有资源将被回收,除了task_struct 结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故 称为僵尸。之所以保留task_struct,是因为task_struct里面保存了进程 的退出码、以及一些统计信息。而其父进程很可能会关心这些信息。
只有在该状态的进程才可能在CPU上运行。而同一时刻可能有多个进程 处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对应 CPU的可执行队列中(一个进程最多只能出现在一个CPU的可执行队列中)。 进程调度器的任务就是从各个CPU的可执行队列中分别选择一个进程在该 CPU 上运行。 S(TASK_INTERRUPTIBLE),可中断的睡眠状态。 处于这个状态的进程因为等待某某事件的发生(比如等待socket连接、 等待信号量),而被挂起。这些进程的task_struct结构被放入对应事件的等 待队列中。当这些事件发生时(由外部中断触发、或由其他进程触发),对 应的等待队列中的一个或多个进程将被唤醒。 D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。 与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进 程是不可中断的。不可中断,指的并不是CPU不响应外部硬件的中断,而 是指进程不响应异步信号。 例如:在进程对某些硬件进行操作时(比如进程调用read系统调用对某 个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码, 并与对应的 物理设备进行交互),可能需要使用 TASK_UNINTERRUPTIBLE状态对进程进行保护,以避免进程与设备交互 的过程被打断,造成设备陷入不可控 的状态