linux进程控制编程

合集下载

进程控制实验报告

进程控制实验报告

一、实验目的本次实验旨在通过Linux操作系统的实践操作,加深对进程控制概念的理解。

通过学习进程的创建、调度、同步、通信等基本操作,掌握进程控制的基本方法,并了解进程间通信的机制。

二、实验环境1. 硬件环境:Intel(R) Core(TM) i5-3210M CPU2.50GHz,4.00GB内存。

2. 软件环境:64位Linux操作系统。

三、实验内容1. 进程的创建与终止2. 进程的调度与优先级3. 进程同步与互斥4. 进程间通信四、实验步骤1. 进程的创建与终止(1)使用`fork()`函数创建子进程,通过比较返回值判断创建是否成功。

```cpid_t pid = fork();if (pid < 0) {perror("fork failed");exit(1);}```(2)使用`exit()`函数终止进程。

```cexit(0);```2. 进程的调度与优先级(1)使用`nice()`函数调整进程优先级。

```cnice(10); // 降低进程优先级```(2)使用`priority_seta()`函数设置进程优先级。

```cstruct sched_param param;param.sched_priority = 10;if (sched_setscheduler(pid, SCHED_RR, &param) == -1) { perror("sched_setscheduler failed");exit(1);}```3. 进程同步与互斥(1)使用`semaphore_t`类型的信号量实现进程同步。

```csemaphore_t sem;sem_init(&sem, 0, 1);sem_wait(&sem);// 执行临界区代码sem_post(&sem);sem_destroy(&sem);```(2)使用`mutex_t`类型的互斥锁实现进程互斥。

3-UNIX&Linux操作系统编程-进程与线程

3-UNIX&Linux操作系统编程-进程与线程

files_struct count close_on_exec open_fs fd[0] fd[1] ……
inode f_mode f_pcs f_flags f_count f_owner f_inode f_op f_version file
fd[255]
file operation routines
exit 函数会执行一些特定的清理操作,还会执行标准I/O库的清理 关闭操作(为所有打开流调用fclose函数,这会使得所有缓冲的 输出数据被更新到相应的设备),然后返回内核
exit与return的区别
C语言关键字return与函数exit()在main函数退出 时有相似之处,但两者有本质的区别:
/usr/include/linux/sched.h #define TASK_RUNNING #define TASK_INTERRUPTIBLE #define TASK_UNINTERRUPTIBLE #define TASK_ZOMBIE #define TASK_STOPPED
0 1 2 4 8
2
用户级进程状态切换
收到信号,执行wake_up( ) TASK_RUNNING 就绪状态 唤醒 wake_up( ) 唤醒 wake_up_interruptible()
调度 schedule( )
TASK_UNINTERRUPTIBLE 等待状态(不可中断) schedule( ) sleep_on( )
TASK_INTERRUPTIBLE 等待状态(可中断) schedule( ) interruptible_sleep_on( )
CPU处理运行 syscall_trace( ) schedule( ) sys_exit( ) do_exit( ) TASK_ZOMBIE 僵死状态

进程编程实验报告

进程编程实验报告

一、实验目的1. 理解进程的概念和进程控制的基本原理。

2. 掌握进程的创建、同步、通信和调度等基本操作。

3. 学习使用操作系统提供的进程控制接口进行进程编程。

4. 提高编程能力和系统分析能力。

二、实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 开发工具:GCC三、实验内容1. 进程的创建2. 进程的同步3. 进程的通信4. 进程的调度四、实验步骤1. 进程的创建(1)编写一个C程序,创建一个子进程,并使子进程执行一个简单的计算任务。

```c#include <stdio.h>#include <unistd.h>int main() {pid_t pid;pid = fork(); // 创建子进程if (pid < 0) {printf("创建子进程失败!\n");return -1;} else if (pid == 0) {// 子进程printf("子进程ID:%d\n", getpid()); int sum = 0;for (int i = 0; i < 10; i++) {sum += i;}printf("子进程计算结果:%d\n", sum); } else {// 父进程printf("父进程ID:%d\n", getpid()); printf("父进程计算结果:%d\n", sum); }return 0;}```2. 进程的同步(1)使用信号量实现两个进程之间的同步。

```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/sem.h>union semun {int val;struct semid_ds buf;unsigned short array;};int main() {key_t key = 1234;int semid = semget(key, 1, 0666); union semun arg;arg.val = 1; // 初始化信号量为1semctl(semid, 0, SETVAL, arg);pid_t pid = fork();if (pid < 0) {printf("创建子进程失败!\n"); return -1;} else if (pid == 0) {// 子进程printf("子进程开始执行...\n"); sem_wait(semid); // 等待信号量int sum = 0;for (int i = 0; i < 10; i++) {sum += i;}printf("子进程计算结果:%d\n", sum); sem_post(semid); // 释放信号量} else {// 父进程printf("父进程开始执行...\n");sem_wait(semid); // 等待信号量int sum = 0;for (int i = 0; i < 10; i++) {sum += i;}printf("父进程计算结果:%d\n", sum); sem_post(semid); // 释放信号量}return 0;}```3. 进程的通信(1)使用共享内存实现两个进程之间的通信。

Linux系统编程之进程控制(进程创建、终止、等待及替换)

Linux系统编程之进程控制(进程创建、终止、等待及替换)

Linux系统编程之进程控制(进程创建、终⽌、等待及替换)进程创建在上⼀节讲解进程概念时,我们提到fork函数是从已经存在的进程中创建⼀个新进程。

那么,系统是如何创建⼀个新进程的呢?这就需要我们更深⼊的剖析fork 函数。

1.1 fork函数的返回值调⽤fork创建进程时,原进程为⽗进程,新进程为⼦进程。

运⾏man fork后,我们可以看到如下信息:#include <unistd.h>pid_t fork(void);fork函数有两个返回值,⼦进程中返回0,⽗进程返回⼦进程pid,如果创建失败则返回-1。

实际上,当我们调⽤fork后,系统内核将会做:分配新的内存块和内核数据结构(如task_struct)给⼦进程将⽗进程的部分数据结构内容拷贝⾄⼦进程添加⼦进程到系统进程列表中fork返回,开始调度1.2 写时拷贝在创建进程的过程中,默认情况下,⽗⼦进程共享代码,但是数据是各⾃私有⼀份的。

如果⽗⼦只需要对数据进⾏读取,那么⼤多数的数据是不需要私有的。

这⾥有三点需要注意:第⼀,为什么⼦进程也会从fork之后开始执⾏?因为⽗⼦进程是共享代码的,在给⼦进程创建PCB时,⼦进程PCB中的⼤多数数据是⽗进程的拷贝,这⾥⾯就包括了程序计数器(PC)。

由于PC中的数据是即将执⾏的下⼀条指令的地址,所以当fork返回之后,⼦进程会和⽗进程⼀样,都执⾏fork之后的代码。

第⼆,创建进程时,⼦进程需要拷贝⽗进程所有的数据吗?⽗进程的数据有很多,但并不是所有的数据都要⽴马使⽤,因此并不是所有的数据都进⾏拷贝。

⼀般情况下,只有当⽗进程或者⼦进程对某些数据进⾏写操作时,操作系统才会从内存中申请内存块,将新的数据拷写⼊申请的内存块中,并且更改页表对应的页表项,这就是写时拷贝。

原理如下图所⽰:第三,为什么数据要各⾃私有?这是因为进程具有独⽴性,每个进程的运⾏不能⼲扰彼此。

1.3 fork函数的⽤法及其调⽤失败的原因fork函数的⽤法:⼀个⽗进程希望复制⾃⼰,通过条件判断,使⽗⼦进程分流同时执⾏不同的代码段。

操作系统实验-进程控制

操作系统实验-进程控制

实验一、进程控制实验1.1 实验目的加深对于进程并发执行概念的理解。

实践并发进程的创建和控制方法。

观察和体验进程的动态特性。

进一步理解进程生命期期间创建、变换、撤销状态变换的过程。

掌握进程控制的方法,了解父子进程间的控制和协作关系。

练习 Linux 系统中进程创建与控制有关的系统调用的编程和调试技术。

1.2 实验说明1)与进程创建、执行有关的系统调用说明 进程可以通过系统调用fork()创建子进程并和其子进程并发执行.子进程初始的执行映像是父进程的一个复本.子进程可以通过 exec()系统调用族装入一个新的执行程序。

父进程可以使用 wait()或 waitpid()系统调用等待子进程的结束并负责收集和清理子进程的退出状态。

fork()系统调用语法:pid_t#include <unistd.h>fork(void);fork 成功创建子进程后将返回子进程的进程号,不成功会返回-1.exec 系统调用有一组 6 个函数,其中示例实验中引用了 execve 系统调用语法:#include <unistd.h>const char * envp[]);path 要装const char *argv[],int execve(const char *path,入的新的执行文件的绝对路径名字符串.argv[] 要传递给新执行程序的完整的命令参数列表(可以为空).envp[] 要传递给新执行程序的完整的环境变量参数列表(可以为空).Exec 执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。

如果 exec 调用失败,它会返回-1。

wait() 系统调用语法:#include <sys/types.h>pid_t#include <sys/wait.h>wait(int *status);status 用pid_t waitpid(pid_t pid,int *status,int option);于保留子进程的退出状态pid 可以为以下可能值:-1 等待所有 PGID 等于 PID 的绝对值的子进程1 等待所有子进程0 等待所有 PGID 等于调用进程的子进程>0 等待 PID 等于 pid 的子进程 option 规定了调用 waitpid 进程的行为:WNOHANG 没有子进程时立即返回WUNTRACED 没有报告状态的进程时返回wait 和 waitpid 执行成功将返回终止的子进程的进程号,不成功返回-1。

Linux下的进程控制块(PCB)

Linux下的进程控制块(PCB)

Linux下的进程控制块(PCB)本⽂转载⾃1. 导语进程在操作系统中都有⼀个户⼝,⽤于表⽰这个进程。

这个户⼝操作系统被称为PCB(进程控制块),在linux中具体实现是 task_struct数据结构。

2. 说明进程控制块(PCB)(系统为了管理进程设置的⼀个专门的数据结构,⽤它来记录进程的外部特征,描述进程的运动变化过程。

系统利⽤PCB来控和管理进程,所以PCB是系统感知进程存在的唯⼀标志。

进程与PCB是⼀⼀对应的)在不同的操作系统中对进程的控制和管理机制不同,PCB中的信息多少不⼀样,通常PCB应包含如下⼀些信息。

1、进程:每个进程都必须有⼀个唯⼀的标识符,可以是字符串,也可以是⼀个数字。

2、进程当前状态 status:说明进程当前所处的状态。

为了管理的⽅便,时会将相同的状态的进程组成⼀个队列,如就绪进程队列,等待进程则要根据等待的事件组成多个,如等待打印机队列、等待磁盘完成队列等等。

3、进程相应的程序和数据地址,以便把PCB与其程序和数据联系起来。

4、进程。

列出所拥有的除CPU外的,如拥有的,打开的⽂件列表等。

5、 priority:进程的优先级反映进程的紧迫程度,通常由⽤户指定和系统设置。

6、现场保护区 cpustatus:当进程因某种原因不能继续占⽤CPU时(如等待打印机),释放CPU,这时就要将CPU的各种状态信息保护起来,为将来再次得到处理机恢复CPU的各种状态,继续运⾏。

7、进程同步与通信机制⽤于实现进程间互斥、同步和通信所需的信号量等。

8、进程所在队列PCB的链接字根据进程所处的现⾏状态,进程相的PCB参加到不同队列中。

PCB链接字指出该进程所在队列中下⼀个进程PCB的⾸地址。

9、与进程有关的其他信息。

如进程记账信息,进程占⽤CPU的时间等。

在linux 中每⼀个进程都由task_struct 来定义. task_struct就是我们通常所说的PCB。

3. 源码struct task_struct{volatile long state; //说明了该进程是否可以执⾏,还是可中断等信息unsigned long flags; // flags 是进程号,在调⽤fork()时给出int sigpending; // 进程上是否有待处理的信号mm_segment_t addr_limit; //进程地址空间,区分内核进程与普通进程在内存存放的位置不同 //0-0xBFFFFFFF for user-thead //0-0xFFFFFFFF for kernel-thread //调度标志,表⽰该进程是否需要重新调度,若⾮0,则当从内核态返回到⽤户态,会发⽣调度volatile long need_resched;int lock_depth; //锁深度long nice; //进程的基本时间⽚//进程的调度策略,有三种,实时进程:SCHED_FIFO,SCHED_RR, 分时进程:SCHED_OTHERunsigned long policy;struct mm_struct *mm; //进程内存管理信息int processor;//若进程不在任何CPU上运⾏, cpus_runnable 的值是0,否则是1 这个值在运⾏队列被锁时更新unsigned long cpus_runnable, cpus_allowed;struct list_head run_list; //指向运⾏队列的指针unsigned long sleep_time; //进程的睡眠时间//⽤于将系统中所有的进程连成⼀个双向循环链表, 其根是init_taskstruct task_struct *next_task, *prev_task;struct mm_struct *active_mm;struct list_head local_pages; //指向本地页⾯unsigned int allocation_order, nr_local_pages;struct linux_binfmt *binfmt; //进程所运⾏的可执⾏⽂件的格式int exit_code, exit_signal;int pdeath_signal; //⽗进程终⽌时向⼦进程发送的信号unsigned long personality;//Linux可以运⾏由其他UNIX操作系统⽣成的符合iBCS2标准的程序int did_exec:1;pid_t pid; //进程标识符,⽤来代表⼀个进程pid_t pgrp; //进程组标识,表⽰进程所属的进程组pid_t tty_old_pgrp; //进程控制终端所在的组标识pid_t session; //进程的会话标识pid_t tgid;int leader; //表⽰进程是否为会话主管struct task_struct *p_opptr,*p_pptr,*p_cptr,*p_ysptr,*p_osptr;struct list_head thread_group; //线程链表struct task_struct *pidhash_next; //⽤于将进程链⼊HASH表struct task_struct **pidhash_pprev;wait_queue_head_t wait_chldexit; //供wait4()使⽤struct completion *vfork_done; //供vfork() 使⽤unsigned long rt_priority; //实时优先级,⽤它计算实时进程调度时的weight值//it_real_value,it_real_incr⽤于REAL定时器,单位为jiffies, 系统根据it_real_value//设置定时器的第⼀个终⽌时间. 在定时器到期时,向进程发送SIGALRM信号,同时根据//it_real_incr重置终⽌时间,it_prof_value,it_prof_incr⽤于Profile定时器,单位为jiffies。

Linux进程控制原语

Linux进程控制原语

Linux/UNIX进程控制原语Linux/UNIX进程控制原语-1 进程控制原语
(2)exec系统调用 系统调用 格式: 六种 六种) 格式:(六种)
int execl(path,arg0,arg1,…,argn,(char *)0)
char *path, *arg0, *arg1, …, *argn ; exec调用进程的正文段被指定的目标文件的正文段 调用进程的正文段被指定的目标文件的正文段 所覆盖,其属性的变化方式与fork成功后从父进程 所覆盖,其属性的变化方式与 成功后从父进程 那里继承属性的方式几乎是一样的。 那里继承属性的方式几乎是一样的。系统中绝大多 数命令都是通过exec来执行的,不但 来执行的, 数命令都是通过 来执行的 不但shell进程所 进程所 创建的子进程使用它来执行用户命令, 创建的子进程使用它来执行用户命令,shell进程本 进程本 身和它的祖先进程也是用exec来启动执行的。 来启动执行的。 身和它的祖先进程也是用 来启动执行的
(6)程序执行说明 (6)程序执行说明 该程序说明主进程创建了一个子程序后, 该程序说明主进程创建了一个子程序后,二 个进程并发执行的情况。 个进程并发执行的情况。 主进程在执行fork系统调用前是一个进程, 主进程在执行 系统调用前是一个进程, 系统调用前是一个进程 执行fork系统调用后,系统中又增加了一个与 系统调用后, 执行 系统调用后 原过程环境相同的子进程, 原过程环境相同的子进程,它们执行程序中 fork语句以后相同的程序,父和子进程 中都有 语句以后相同的程序, 语句以后相同的程序 自己的变量pid,但它们的值不同,它是 自己的变量 ,但它们的值不同,它是fork调 调 用后的返回值,父进程的pid为大于 的值, 为大于0的值 用后的返回值,父进程的 为大于 的值,它 代表新创建子进程的标识符,而子进程的pid为 代表新创建子进程的标识符,而子进程的 为 0。这样父子进程执行相同一个程序,但却执行 。这样父子进程执行相同一个程序, 不同的程序段。子进程执行if(pid= = 0)以后的 不同的程序段。子进程执行 以后的 大括号内的程序, 语句; 大括号内的程序,即execlp语句;而父进程执 语句 以后的大括号内的程序。 行else以后的大括号内的程序。 以后的大括号内的程序

第6章 linux进程控制开发及多线程编程

第6章  linux进程控制开发及多线程编程

进程的状态
进程是程序的执行过程,根据它的生命周期可以划分成3种 状态。 执行态:该进程正在运行,即进程正在占用CPU。 就绪态:进程已经具备执行的一切条件,正在等待分配 CPU的处理时间片。 等待态:进程不能使用CPU,若等待事件发生(等待的 资源分配到)则可将其唤醒。
Linux下进程地址空间(1)
互斥锁线程控制 (1)
在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态 的线程能够对共享资源进行操作。若其他线程希望上锁一个 已经被上锁的互斥锁,则该线程就会挂起,直到上锁的线程 释放掉互斥锁为止。
互斥锁机制主要包括下面的基本函数。 互斥锁初始化: pthread_mutex_init() 互斥锁上锁: pthread_mutex_lock() 互斥锁判断上锁:pthread_mutex_trylock() 互斥锁解锁: pthread_mutex_unlock() 消除互斥锁: pthread_mutex_destroy()
示例
阅读并执行示例7-2-4 开始
教材P216-P217
fork()
程序功能: (1)使用fork创建一个子进程, 然后让其子进程暂停5s(sleep函 数)。 (2)父进程使用waitpid,参数 WNOHANG使进程不会阻塞; (3)若子进程退出,则waitpid返 回子进程号,若没有则waitpid返 回0,并且父进程每隔一秒循环判 断。
因此,可以通过返回值来判定该进程是父进程还是子进程。
fork示例
1.Fork返回两个值返回到哪里??
int main(void)
{

pid_t result;
2.怎样区分是父、子进程??

result = fork();

Linux程序设计上机指导书3:Linux进程控制

Linux程序设计上机指导书3:Linux进程控制

,也可以在程 而exec 调 exec 前后的进上机三:Linux 进程控制1. 目的(1)掌握系统调用fork(),exex(),exit() 等实现进程创建;(2) 掌握进程的终止方式(return 、exit 、_exit 、abort ); (3) 掌握僵尸进程的产生和避免,以及 wait,waitpid 的使用;(4 )了解守护进程的创建。

2. 内容主要上机分析代码文件。

systemtest.c 6-3.C 6-4.C 6-8.C 6-9.C 其他略。

3. 步骤1) Linux 进程的创建创建进程可以采用几种方式。

可以执行一个程序(这会导致新进程的创建) 序内调用一个 fork 或exec 来创建新进程。

fork 调用会导致创建一个子进程, 用则会用新程序代替当前进程上下文。

exec 系列函数并不创建新进程,调用程ID 是相同的。

exec 系列函数如下。

exec函数的主要工作是清除父进程的可执行代码映像,用新程序的代码覆盖调用exec 的进程代码。

如果 exec执行成功,进程将从新程序的main函数入口开始执行。

调用 exec后,除进程ID保持不变外,还有下列进程属性也保持不变。

(1) 进程的父进程ID。

(2) 实际用户ID和实际用户组ID。

(3) 进程组ID、会话ID和控制终端。

(4) 定时器的剩余时间。

(5) 当前工作目录及根目录。

(6) 文件创建掩码UMASK。

(7) 进程的信号掩码。

与exec系统调用不同,system 将外部可执行程序加载执行完毕后继续返回调用进程。

system的返回值就是被加载的程序的返回值。

【例6.3】设计一个程序,用fork函数创建一个子进程,在子进程中,要求显示子进程号与父进程号,然后显示当前目录下的文件信息,在父进程中同样显示子进程号与父进程号/*6-3.c 将一个进程分为两个一样的进程,打印出进程的相关信息*/#i nclude<stdio.h> /*文件预处理,包含标准输入输出库*/#i nclude<stdlib.h> /*文件预处理,包含system、exit等函数库*/#in clude< uni std.h> /*文件预处理,包含 fork、getpid、getppid 函数库*/#in clude<sys/types.h> /*文件预处理,包含fork函数库*/int mai n () /*C程序的主函数,开始入口*/result=fork(); /*调用fork函数,返回值存在变量result中*/6-3.c -Q 6-3【步骤1】设计编辑源程序代码。

linux 中的进程处理和控制方式

linux 中的进程处理和控制方式

linux 中的进程处理和控制方式Linux 是一种广泛使用的操作系统,它具有强大的进程处理和控制功能。

在 Linux 系统中,进程是进行任务的基本单位,它们可以同时运行,互相通信,共享资源,因此进程处理和控制是 Linux 系统重要的组成部分。

Linux 提供了多种方式来处理和控制进程。

以下是一些常见的方式:1. 创建新进程:在 Linux 系统中,可以通过 fork() 系统调用创建一个新的子进程。

子进程是通过复制父进程的内存空间、文件描述符和其他资源来创建的。

这样可以实现并行处理任务,提高系统的效率。

创建新进程时,可以使用 exec() 系统调用来加载一个新的程序运行。

2. 进程调度:Linux 使用调度器(scheduler)来决定哪个进程在何时执行。

调度算法会根据进程的优先级(priority)和调度策略来决定进程的执行顺序。

常见的调度策略包括先进先出(FIFO)、最短作业优先(SJF)、轮转(Round Robin)等。

通过合理的调度算法,可以提高系统的响应速度和资源利用率。

3. 进程间通信:在 Linux 中,进程之间可以通过多种方式进行通信。

其中最常用的方式是通过管道(pipe)、信号(signal)和共享内存(shared memory)来进行进程间的数据交换。

管道可以实现进程的单向通信,信号可以用于进程之间的异步通信,而共享内存可以让多个进程共享同一片内存区域,实现高效的数据交换。

4. 进程控制:Linux 提供了多个命令和系统调用来控制进程的行为。

例如,可以使用 ps 命令来查看系统中正在运行的进程,使用kill 命令发送信号终止进程,使用 nice 命令来改变进程的优先级等。

此外,还可以使用进程控制信号(Process Control Signals)来改变进程的状态,如暂停、继续、停止等。

5. 进程管理工具:Linux 提供了一些进程管理工具来帮助用户更方便地处理和控制进程。

操作系统原理实验4-进程控制

操作系统原理实验4-进程控制

《操作系统原理》实验报告
实验序号:4 实验项目名称:进程控制
一、实验目的及要求
1. 加深对进程信号量的理解。

2. 理解进程同步与互斥机制。

3. 掌握Linux操作系统下的进程控制编程。

二、实验设备(环境)及要求
1.虚拟机VMware Workstation、Ubuntu操作系统和C语言编程。

2.编写一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按Ctrl C键),当捕捉到中断信号后,父进程调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下面信息后终止:
child process 1 is killed by parent!
child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止:
parent process is killed!
三、实验内容与步骤
代码:
在终端上进行测试
四、实验结果与数据处理
五、分析与讨论
了解了计算机进程的管理以及signal()函数的作用。

六、教师评语成绩。

第7章 进程控制程序设计

第7章 进程控制程序设计

7.2.4 进程同步、互斥
一组并发进程按一定的顺序执行的过程称为进程间的同 步。具有同步关系的一组并发进程称为合作进程,合作 进程间互相发送的信号称为消息或事件。 进程互斥是指当有若干进程都要使用某一共享资源时, 任何时刻最多允许一个进程使用,其他要使用该资源的 进程必须等待,直到占用该资源者释放了该资源为止。 临界资源:操作系统中将一次只允许一个进程访问的资 源称为临界资源。进程中访问临界资源的那段程序代码 称为临界区。为实现对临界资源的互斥访问,应保证诸 进程互斥的进入各自的临界区。 死锁:多个进程因竞争资源而形成一种僵局,若无外力 作用,这些进程都将永远不能再向前推进。
第7章 进程控制程序设计
7.1 7.2 7.3 7.4 7.5 项目目标 进程控制概述 进程控制编程 守护进程 农业信息采集控制系统主程序设计
7.1 项目目标
通过本章节的学习,理解进程控制的方法。设 计数据采集显示系统的主进程,实现主进程基 本框架。 本章知识点:
Linux下的进程概念 Linux进程管理相关的系统调用 守护进程
7.3.2 进程的创建
在Linux中创建一个新进程的方法是使用fork()函数。 fork()函数用于从已存在的进程中创建一个新进程。新 进程称为子进程,而原进程称为父进程。使用fork()函 数得到的子进程是父进程的一个复制品,它从父进程处 继承了整个进程的地址空间,包括进程上下文、代码段、 进程堆栈、内存信息、打开的文件描述符、信号控制设 定、进程优先级、进程组号、当前工作目录、根目录、 资源限制和控制终端等,而子进程所独有的只有它的进 程号、资源使用和计时器等。 因为子进程几乎是父进程的完全复制,所以父子两个进 程会运行同一个程序。因此需要用一种方式来区分它们, 并使它们照此运行,否则,这两个进程不可能做不同的 事。

linux实验报告

linux实验报告

实验报告6课程名称:Linux基础实验名称:Linux进程控制学生姓名:汪磊班级:计科132 学号:090313217指导老师:钱振江成绩:一、实验目的1.掌握进程的创建,用fork产生的子进程与父进程的关系;2.掌握exec函数族的应用。

二、实验任务与要求1.熟悉父进程创建一个子进程,父进程与子进程之间的数据结构与变量存放的问题;2.子进程与父进程间的关系;3.execl、execv函数的应用;4.execlp函数的应用;5.execle函数的应用;三、实验工具与准备计算机PC机,Linux Ubuntu操作系统四、实验步骤与操作指导1.调试下列程序。

步骤1 用vi编辑程序6-1.c。

[root@localhost root]# vi 6-1.c#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 = 3;} else { /*父进程执行*/message = "This is the parent\n";n = 6;}for(; n > 0; n--) {printf(message);sleep(1);}return 0;}步骤2 用gcc编译程序。

用gcc的”-o”选项,将6-1.c程序编译成可执行文件6-1,输入如下:[root@localhost root]#gcc 6-1.c –o 6-1步骤3 运行程序。

linux task_struck 进程控制块 和kernel_thread解析

linux task_struck 进程控制块 和kernel_thread解析

(0x0001 | STICKY_TIMEOUTS)
#define PER_SVR3
(0x0002 | STICKY_TIMEOUTS)
#define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
#define PER_WYSEV386
/* * This structure defines the functions that are used to load the binary formats that * linux accepts. */
struct linux_binfmt { struct linux_binfmt * next; struct module *module; int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); int (*load_shlib)(struct file *); int (*core_dump)(long signr, struct pt_regs * regs, struct file * file); unsigned long min_coredump; /* minimal dump size */
/* CPU time in ms */
/* Maximum filesize */
/* max data size */
/* max stack size */
/* max core file size */
/* max resident set size */
/* max number of processes */
atomic_t __count; /* reference count */ atomic_t processes; /* How many processes does this user have? */ atomic_t files; /* How many open files does this user have? */

Linux程序设计——技术技巧与项目实践---进程调度与通信编程--第7章解析

Linux程序设计——技术技巧与项目实践---进程调度与通信编程--第7章解析
2018X下的进程概述 7.2 进程的系统调用 7.3 进程间通信 7.4 信号 7.5 守护进程 7.6 实战技巧 巧妙使用Tab键
2018/11/3
7.1 Linux下的进程概述
7.1.1 进程的概念
2
• Linux作为多用户操作系统,支持多道程序设计、分时处理和软实时处 理,带有微内核的一些特征,在程序设计时需引进进程机制。当前正 在运行的程序称为进程,对进程的监视和控制是linux系统管理员的核 心任务。管理员可以终止或重启一个进程,也可以指定一个新的优先 级。命令“ps”和“top”用于查看当前进程列表。如何用这些命令管理 linux系统中的进程请参见本书第三章中的“3.7 进程管理命令”一节。 • 监视linux的标准工具ps(process status)返回正在运行程序的信息, 包括程序运行的用户名,CPU运行份额和时间。如果要手工终止程序 或确定哪个程序让系统变慢,这些信息很有用。监视和控制进程很有 必要。 • 使用ps、top、kill和renice命令可以看到进程的运行情况并对它们进行 控制。进程是操作系统调度单位,进程PCB用一个名为task_struct的结 构体表示,定义在/include/linux/sehed.h中。每个task_struct结构占 1680字节,系统中最大进程数由系统物理内存大小决定。每当创建一 个新进程时,便在内存中申请一个空task_struct结构,填入需要的信息。
• • • • • •
2018/11/3
5
• • • • •
5)unsigned long policy 表示该进程的进程调度策略。调度策略有: · SCHED_OTHER 0,非实时进程,用基于优先权的轮转法。 · SCHED_ FIFO 1,实时进程,用先进先出算法。 · SCHED_RR 2,实时进程,用基于优先权的轮转法。

进程

进程

因等待事件发生而唤 醒
就绪
时间片到
运行
等待某个事件发生而阻塞
阻塞
图 6_1
进程管理
1. 启动进程
进程加载有两种途径:手工加载和调度加载 手工加载: 手工加载又分为前台加载,和后台加载。 前台加载:是手工加载一个进程最常用方式。一般地,当用户输入一个命令,如“ls -l” 时就已经产生了一个进程,并且是一个前台进程。 后台加载:往往是在该进程非常耗时,且用户也不急着需要结果的时候启动。常常用户 在终端输入一个命令时同时在命令尾加上一个“&”符号。 调度加载: 在系统中有时要进行比较费时而且占用资源的维护工作, 并且这些工作适合在深夜而无 人值守时运行,这时用户就可以事先进行调度安排,指定任务运行的时间或者场合,到时系 统就会自动完成一切任务。 2. 调度进程
/*pidandppid.c*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { printf(“PID = %d\n”, getpid()); printf(“PPID = %d\n”, getppid()); exit(0); } 通过编译后,运行程序得到以下结果(该值在不同的系统上会有不同的值) [root@localhost process]#./pidandppid
用系统的物理内存来容纳进程本身和它的有关数据、 要在文件系统中打开和使用文件、 并且 可能直接或间接的使用系统的物理设备,例如打印机、扫描仪等。由于这些系统资源是由所 有进程共享的, 所以操作系统必须监视进程和它所拥有的系统资源, 使它们可以公平地拥有 系统资源以得到运行。 小知识:假设有三道程序 A、B、C 在系统中运行。程序一旦运行起来,我们就称它为 进程,因此称它们为三个进程 Pa、Pb、Pc。假定进程 Pa 执行到一条输入语句,因为这时 要从外设读入数据,于是进程 Pa 主动放弃 CPU。此时操作系统中的调度程序就要选择一个 进程投入运行,假设选中 Pc,这就会发生进程切换,从 Pa 切换到 Pc。同理,在某个时刻 可能切换到进程 Pb。从某一时间段看,三个进程在同时执行,从某一时刻看,只有一个进 程在运行,我们把这几个进程的伪并行执行叫做进程的并发执行。

操作系统原理及应用(Linux)(第2版)课程教学大纲

操作系统原理及应用(Linux)(第2版)课程教学大纲

《操作系统》课程教学大纲一、课程基本信息课程名称:操作系统先修课程:《计算机导论》(或《计算机应用基础》)、《C语言程序设计》、《数据结构》、《计算机组成原理》适用专业:计算机科学与技术、软件工程、网络工程等计算机及相关专业。

课程类别:专业教育必修课程/基础课程课程总学时:56-72 (其中理论40-56学时,实验16学时)二、课程目标通过本课程的学习,使学生具备下列能力:1.能够准确理解及掌握操作系统的基本概念、基本功能和基本原理,理解操作系统的整体运行过程。

2.能够理解及掌握操作系统的各组成部分,包括进程管理、调度、内存管理、文件管理、设备管理的功能及策略、算法、机制及相互关系。

3.能够运用操作系统原理、方法与技术分析问题和解决问题,并能利用C 语言描述相关算法。

4.在理解及掌握操作系统原理及算法的基础上,在进行硬件配置、软件设计及编程过程中,能够在资源和效率方面综合考虑,完善提高设计方案,提高利用操作系统知识解决实际问题的能力。

三、教学内容、要求及重难点第一章操作系统引论(3学时)教学要求:1.掌握操作系统的概念及功能,掌握操作系统的分类;2.掌握操作系统在计算机系统中的地位和作用;理解操作系统的大致运行过程;3.理解操作系统的特征;了解各种类型操作系统的特点及服务适应情况;4.了解操作系统的结构特征及发展概况,发展趋势。

教学重点:操作系统的概念、作用;操作系统的分类;操作系统的特征;操作系统的功能;操作系统的结构设计。

教学难点:操作系统的特征;操作系统的功能。

[实验名称]Linux系统管理及命令的使用[实验类型]验证型[实验要求]1.熟练Linux系统常用命令的使用;2.掌握Vi编辑器的使用方法;3.练习Linux shell的作用和主要分类,能编写简单的shell程序[实验学时]2学时第二章进程管理(10学时)教学要求:1.掌握进程的概念与特征;2.掌握进程的结构及进程控制的方法;3.掌握进程的同步与互斥,以及实现进程同步问题的硬件方法和软件方法;4.能用信号量机制解决进程的同步问题;5.掌握线程的基本概念;6.基本掌握利用管程解决同步问题的方法。

Linux进程控制实验报告1

Linux进程控制实验报告1

Linux进程控制实验报告实验名称: Linux进程控制实验要求: 一.编写一个Linux系统C程序,由父亲创建2个子进程,再由子进程各自从控制台接收一串字符串,保存在各自的全局字符串变量中,然后正常结束。

父进程调用waitpid等待子进程结束,并分别显示每个子进程的进程标识号和所接收的字符串。

二.父进程创建一子进程,父进程向子进程发送数据,子进程接收数据,并写入文件。

关键问题:一.需要用共享内存或使用vfork()函数创建子进程进行进程之间的数据共享及传递。

父进程必须等待子进程结束才能继续执行。

二.注意信号的使用。

子进程需等待父进程发送信号才执行相应操作。

父,子进程之间的通信需要用到共享内存或者父进程用vfork()创建子进程。

设计思路:一.使用共享内存实现数据共享,子进程一用shmaddr1保存输入的字符串,子进程二用shmaddr2保存字符串。

父进程等待两个子进程分别输入完字符串,然后再分别把数据显示出来。

二.用共享内存的方法来实现父子进程之间的通信,首先建立共享内存区域,然后建立子进程,并让子进程等待父进程信号。

在父进程中输入字符串,并把此字符串保存在共享内存区域,然后向子进程发出信号SIGUSR1,若子进程接受到SIGUSR1信号,则把父进程保存在共享内存区域的字符串取出,并把它写入文件。

关键代码:一.#include <unistd.h>#include <stdio.h>#include </usr/include/sys/types.h>#include <string.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/shm.h>#define KEY 1234#define SIZE 64char* shmaddr1;char* shmaddr2;main(){pid_t pid1;pid_t pid2;char* str1;char* str2;int shmid1;int shmid2;shmid1=shmget(23,SIZE,IPC_CREAT|0600);shmid2=shmget(24,SIZE,IPC_CREAT|0600);if ((pid1=fork())<0){printf("creat 1 fail!\n");exit(0);}else if(pid1==0){shmaddr1=(char*)shmat(shmid1,NULL,0);printf("creat 1 successfully!\n");scanf("%s",str1);printf("you enter:%s\n",str1);strcpy(shmaddr1,str1);shmdt(shmaddr1);exit(0);}wait();if ((pid2=fork())<0){printf("creat 2 fail!\n");exit(0);}else if(pid2==0){shmaddr2=(char*)shmat(shmid2,NULL,0);printf("creat 2 successfully!\n");scanf("%s",str2);printf("you enter:%s\n",str2);strcpy(shmaddr2,str2);shmdt(shmaddr2);exit(0);}wait();shmaddr1=(char*)shmat(shmid1,NULL,0);shmaddr2=(char*)shmat(shmid2,NULL,0);printf("one is %s\n",shmaddr1);printf("two is %s\n",shmaddr2);shmdt(shmaddr1);shmdt(shmaddr2);shmctl(shmid1,IPC_RMID,NULL);shmctl(shmid2,IPC_RMID,NULL);exit(0);}实验结果:二.#include<signal.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<sys/ipc.h>#include<sys/shm.h>#define key 1024#define size 160static void sign(int);int shmid;char* shmaddr;main(){pid_t pid;char str[20];shmid=shmget(key,size,IPC_CREAT|0600);if((pid=fork())<0){perror("创建子进程错误!\n");exit(0);}else if(pid==0){if(signal(SIGUSR1,sign)==SIG_ERR){printf("SIGUSR1错误!\n");exit(0);}pause();printf("子进程结束!\n");exit(0);}sleep(1);shmaddr=(char*)shmat(shmid,NULL,0);printf("请输入字符串:");scanf("%s",str);strcpy(shmaddr,str);shmdt(shmaddr);kill(pid,SIGUSR1);wait();shmctl(shmid,IPC_RMID,NULL);}static void sign(int signnum){int fd;char* shmaddr;if(signnum==SIGUSR1){printf("子进程接收到SIGUSR1.\n");shmaddr=(char*)shmat(shmid,NULL,0);if((fd=open("testfile.txt",O_RDWR|O_CREAT|O_TRUNC))==-1){printf("\n打开文件错误!\n");return 0;}else{printf("写入:%s\n",shmaddr);write(fd,shmaddr,20);close(fd);}shmdt(shmaddr);}}实验总结:经过此次实验,我学会了如何通过shm共享内存实现各进程间的数据共享,以及如何在父子进程之间发送信号和传输数据以及一些保存文件的操作,通过这次实验我受益良多。

进程的控制_实验报告

进程的控制_实验报告

### 实验目的1. 理解操作系统进程控制的基本概念和原理。

2. 掌握进程的创建、同步、通信和终止等操作。

3. 熟悉Linux系统中的进程控制命令和系统调用。

4. 理解进程调度算法的基本原理和实现方法。

### 实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 编译器:gcc4. 开发工具:vim### 实验内容本实验主要涉及以下内容:1. 进程的创建与终止2. 进程同步与通信3. 进程调度算法#### 1. 进程的创建与终止实验一:利用fork()创建进程```c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); printf("Child process is running...\n");sleep(2);printf("Child process is exiting...\n");return 0;} else {printf("Parent process, PID: %d\n", getpid()); printf("Parent process is running...\n");sleep(3);printf("Parent process is exiting...\n");wait(NULL);}return 0;}```实验二:利用exec()创建进程```c#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {execlp("ls", "ls", "-l", (char )NULL); printf("execlp() error\n");return 1;} else {wait(NULL);}return 0;}```实验三:进程终止```c#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>int main() {pid_t pid;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); sleep(2);printf("Child process is exiting...\n");exit(0);} else {wait(NULL);}return 0;}```#### 2. 进程同步与通信实验四:使用信号实现进程同步```c#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>int main() {pid_t pid;int status;int signalNo = 1;pid = fork();if (pid < 0) {printf("fork() error\n");return 1;} else if (pid == 0) {printf("Child process, PID: %d\n", getpid()); while (1) {pause();printf("Child process is running...\n"); }} else {printf("Parent process, PID: %d\n", getpid()); sleep(1);kill(pid, signalNo);wait(NULL);}return 0;}```实验五:使用管道实现进程通信```c#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {int pipefd[2];pid_t pid;char buffer[100];if (pipe(pipefd) == -1) {printf("pipe() error\n"); return 1;}pid = fork();if (pid < 0) {printf("fork() error\n"); return 1;} else if (pid == 0) {close(pipefd[0]);read(pipefd[1], buffer, sizeof(buffer));printf("Child process, PID: %d, Received: %s\n", getpid(), buffer);} else {close(pipefd[1]);write(pipefd[0], "Hello, Child!\n", 14);wait(NULL);}return 0;}```#### 3. 进程调度算法实验六:先来先服务(FCFS)调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#define NUM_PROCESSES 5#define TIME_QUANTUM 2typedef struct {int pid;int arrival_time;int burst_time;} Process;int main() {Process processes[NUM_PROCESSES] = {{1, 0, 5},{2, 1, 3},{3, 2, 4},{4, 3, 2},{5, 4, 1}};int i, j, time = 0, completed = 0;int wait_time[NUM_PROCESSES], turnaround_time[NUM_PROCESSES]; // Calculate waiting timefor (i = 0; i < NUM_PROCESSES; i++) {wait_time[i] = 0;}for (i = 0; i < NUM_PROCESSES; i++) {for (j = 0; j < i; j++) {wait_time[i] += processes[j].burst_time;}}// Calculate turnaround timefor (i = 0; i < NUM_PROCESSES; i++) {turnaround_time[i] = wait_time[i] + processes[i].burst_time;}// Calculate average waiting time and turnaround timeint total_wait_time = 0, total_turnaround_time = 0;for (i = 0; i < NUM_PROCESSES; i++) {total_wait_time += wait_time[i];total_turnaround_time += turnaround_time[i];}printf("Average waiting time: %.2f\n", (float)total_wait_time / NUM_PROCESSES);printf("Average turnaround time: %.2f\n",(float)total_turnaround_time / NUM_PROCESSES);return 0;}```实验七:时间片轮转调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#define NUM_PROCESSES 5#define TIME_QUANTUM 2typedef struct {int pid;int arrival_time;int burst_time;} Process;int main() {Process processes[NUM_PROCESSES] = {{1, 0, 5},{2, 1, 3},{3, 2, 4},{4, 3, 2},{5, 4, 1}};int i, j, time = 0, completed = 0;int wait_time[NUM_PROCESSES], turnaround_time[NUM_PROCESSES]; // Calculate waiting timefor (i = 0; i < NUM_PROCESSES; i++) {wait_time[i] = 0;}for (i = 0; i < NUM_PROCESSES; i++) {for (j = 0; j < i; j++) {wait_time[i] += processes[j].burst_time;}}// Calculate turnaround timefor (i = 0; i < NUM_PROCESSES; i++) {turnaround_time[i] = wait_time[i] + processes[i].burst_time;}// Calculate average waiting time and turnaround timeint total_wait_time = 0, total_turnaround_time = 0;for (i = 0; i < NUM_PROCESSES; i++) {total_wait_time += wait_time[i];total_turnaround_time += turnaround_time[i];}printf("Average waiting time: %.2f\n", (float)total_wait_time / NUM_PROCESSES);printf("Average turnaround time: %.2f\n",(float)total_turnaround_time / NUM_PROCESSES);return 0;}```### 实验总结通过本次实验,我对操作系统进程控制有了更深入的了解。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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"); }
T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。
向进程发送一个SIGSTOP信号,它就会因响应该信号而进入 TASK_STOPPED状态(除非该进程本身处于 TASK_UNINTERRUPTIBLE状态而不响应信号)。(SIGSTOP与SIGKILL 信号一样,是非常强制的。不允许用户进程通过 signal系列的系统调用 重新设置对应的信号处理函数。) 向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢 复到TASK_RUNNING状态。
子进程结束状态值。 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,所以它总能了解是哪一 个子进程终止了。
第十讲
进程控制
LOGO

LINUX
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数

State 进程在执行过程中会根据环境来改变state。Linux进程有以下状态:
R (TASK_RUNNING),可执行状态
printf("hello\n");
}
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数
waitpid函数
1. wait 和waitpid函数
如果子进程在父进程之前终止,那么父进程又如何能在 做相应检查时得到子进程的终止状态呢? 内核为每个终止子进程保存了一定量的信息,所以当终止 进程的父进程调用 wait或waitpid 时,可以得到有关信 息。这种信息至少包括进程 ID、该进程的终止状态、以 反该进程使用的 CPU时间总量。内核可以释放终止进程 所使 用的所有存储器,关闭其所有打开文件。 调用wait或waitpid的进程可能会: 1.暂时停止目前进程的执行,直到有信号来到或子进程结束。 2如果在调用 wait()时子进程已经结束,则 wait()会立即返回
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()); }
目录
一、进程标识 二、fork函数
LINUX
三、vfork 函数 四、waitpid函数 五、exec 函数
exec 函数
1. exec 函数
上一节曾提及用vfork函数创建子进程后,子进程往往要调用一 种exec函数以执行另一个程序。 当进程调用一种exec函数时,该进程完全由新程序代换,而新 程序则从其 main函数开始执行。 因为调用exec并不创建新进程,所以前后的进程ID并未改变。 exec只是用另一个新程序替换了 当前进程的正文、数据、堆 和栈段。
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 [] );
进程标识
1.引言 本章介绍 UNIX的进程控制,包括: 创建新进程 执行程序 进程终止
进程标识
2.进程标识
每个进程都有一个非负整型的唯一进程 ID。因为进程 ID 标识符总是唯一的,常将其用做其 他标识符的一部分以保证 其唯一性。 专用的进程: 进程 ID0 是调度进程,常常被称为交换进程 (swapper)。该 进程并不执行任何磁盘上的程序—它是内核的一部分,因此 也被称为系统进程。 进程 ID1 通常是init进程,在自举过程结束时由内核调用。 示例: ps –aux 显示其他用户启动的进程(a) 查看系统中属于自己的进程(x) 启动这个进程的用户和它启动的时间(u)
只有在该状态的进程才可能在CPU上运行。而同一时刻可能有多个进程 处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对应 CPU的可执行队列中(一个进程最多只能出现在一个CPU的可执行队列中)。 进程调度器的任务就是从各个CPU的可执行队列中分别选择一个进程在该 CPU 上运行。 S(TASK_INTERRUPTIBLE),可中断的睡眠状态。 处于这个状态的进程因为等待某某事件的发生(比如等待socket连接、 等待信号量),而被挂起。这些进程的task_struct结构被放入对应事件的等 待队列中。当这些事件发生时(由外部中断触发、或由其他进程触发),对 应的等待队列中的一个或多个进程将被唤醒。 D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。 与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进 程是不可中断的。不可中断,指的并不是CPU不响应外部硬件的中断,而 是指进程不响应异步信号。 例如:在进程对某些硬件进行操作时(比如进程调用read系统调用对某 个设备文件进行读操作,而read系统调用最终执行到对应设备驱动的代码, 并与对应的 物理设备进行交互),可能需要使用 TASK_UNINTERRUPTIBLE状态对进程进行保护,以避免进程与设备交互 的过程被打断,造成设备陷入不可控 的状态
目录
一、进程标识 二、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
相关文档
最新文档