Unix高级编程009_进程关系
unix环境高级编程--第8章 进程控制(上)

发信人: scircle (yuanyuan), 信区: Security标题: unix环境高级编程--第8章进程控制(上)发信站: BBS 水木清华站 (Mon Mar 27 15:58:55 2000)第八章〓进程控制8 1〓引言本章介绍Unix的进程控制,包括创建新进程、执行程序和进程终止。
我们也说明进程的各种ID〖CD2〗实际、有效和保存的用户和组ID,以及它们如何受到进程控制原语的影响。
本章也包括了解释器文件和system函数。
本章以大多数Unix系统所提供的进程会计机制结束。
这使我们从一个不同角度了解进程控制功能。
8 2〓进程标识每个进程都有一个非负整型的唯一进程ID。
因为进程ID标识符总是唯一的,常将其用作为其它标识符的一部分以保证其唯一性。
在5 13节中的tmpnam函数将进程ID作为名字的一部分创建一个唯一的路径名。
有某些专用的进程:进程ID0是调度进程,常常被称为交换进程(swapper)。
该进程并不执行任何磁盘上的程序。
〖CD2〗它是系统核的一部分,因此也被称为系统进程。
进程ID1通常是init进程,在自举过程结束时由系统核调用。
该进程的程序文件在Unix的较早版本中是/etc/init,在版新版本中是/sbin/init。
此进程负责在系统核自举后起动一个Unix系统。
init通常读与系统有关的初始化文件(/etc/rc*文件),并将系统引导到一个状态(例如多用户)。
init进程决不会终止。
它是一个普通的用户进程(与交换进程不同,它不是一个在系统核内的系统进程),但是它以超级用户特权运行。
在本章稍后部分会说明init如何成为所有孤儿进程的父进程。
在某些Unix的虚存实现中,进程ID2是页精灵进程(pagedaemon)。
此进程负责支持虚存系统的请页操作。
除了进程ID,每个进程还有一些其它标识符。
下列函数返回这些标识符。
#include <sys/types h>#include <unistd h>pid 迹茫模*常病絫 getpid(voide;〓〓〖CD2〗调用进程的进程IDpid 迹茫模*常病絫 getppid(void);〓〓〖CD2〗调用进程的父进程IDuid 迹茫模*常病絫 getuid(void);〓〓〖CD2〗调用进程的实际用户IDuid 迹茫模*常病絫 geteuid(void);〓返回:〓〓〖CD2〗调用进程的有效用户IDgid 迹茫模*常病絫 getgid(void);〓〓〖CD2〗调用进程的实际组IDgid 迹茫模*常病絫 getegid(void);〓〓〖CD2〗调用进程的有效组ID注意,这些函数都没有出错返回,在下一章中讨论fork函数时,将进一步讨论父进程ID。
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 僵死状态
UNIX进程环境与进程控制

关于fork的说明
• 由fork创建的新进程被称为子进程(child process)。该函 数被调用一次,但返回两次。两次返回的区别是:
–子进程的返回值是0; –父进程的返回值则是新子进程的进程I D。
• 将子进程ID返回给父进程的理由是:因为一个进程的子 进程可以多于一个,所以没有一个函数使一个进程可以 获得其所有子进程的进程ID。 • fork使子进程得到返回值0的理由是:一个进程只会有一 个父进程,子进程总是可以调用getppid以获得其父进程 的进程ID。 • 由于ID为0的进程总是由交换和调度进程使用,所以一 个子进程的进程I D不可能为0。
• 进程的非正常退出:
– abort():除非信号SIGABRT被捕获,abort()将使内核 向进程自己发送SIGSBRT信号,然后非正常退出。 – killed:进程被信号终止。
进程的退出过程
• 一般来说进程的退出过程大致如下:
– A.关闭自己打开的I/O流和文件描述符; – B.调用atexit()或on_exit()定义的函数; – C.释放进程在堆空间申请的内存; – D.回收进程空间; – E.回收进程id号。
• 功能:实现函数间的跳转—长跳转。 • 用法:
– #include <setjmp.h> – int setjmp(jmp_buf env) ; –返回值:若直接调用则为0,若从longjmp返回则为非0 – void longjmp(jmp_buf env, int val) ; –第一个参数是在调用setjmp时所用的env;第二个val,是 个非0值,它成为从setjmp处返回的值。使用第二个参数的 原因是对于一个setjmp可以有多个longjmp。可以在按 longjmp的调用顺序安排val值。
unix环境高级编程--第9章 进程关系

发信人: scircle (yuanyuan), 信区: Security标题: unix环境高级编程--第9章进程关系发信站: BBS 水木清华站 (Mon Mar 27 16:00:58 2000)第九章〓进程关系9 1〓引言在上一章我们已了解到进程之间具有关系。
首先,每个进程有一个父进程。
当子进程终止时,父进程会得到通知并能取得子进程退出状态。
在8 6节说明waitpicl函数时,我们也提到了进程组,以及如何等待进程组中的任一个进程终止。
本章的更详细地说明进程组以及POSIX 1引进的对话期新概念。
我们也将介绍login shell(是我们登录时为我们调用的)和所有从login shell起动的进程之间的关系。
在说明这些关系时不可能不谈及信号,而谈论信号又需要很多本章介绍的概念。
如果你不熟悉Unix信号,则可能先要浏览一下第十章。
9 2〓终端登录先看一看登录到Unix系统时所执行的各个程序。
在早期的Unix系统中,例如Versi on7,用户用哑终端(通过RS-232连到主机)进行登录。
终端或者是在地的(直接连接)或者是远程的(通过调制解调器连接)。
在这两种情况下,login都经由系统核中的终端设备驱动程序。
例如,在PDP-11上常用的设备是DH-11和DZ-11。
因为连到主机上的终端设备数已经确定,所以同时的login数也就有了已知的上限。
下面说明的登录过程适用于使用一个RS-232终端登录到Unix系统中。
4 3+BSD终端登录登录过程在过去十五年中并没有多少改变。
系统管理者创建一个通常名为/etc/thys的文件,其中,每个终端设备有一行。
每一行说明设备名和传到getty程序的参数。
这些参数说明了终端的波特率等。
当系统自举时,系统核创建进程ID1,也就是init进程。
init进程供系统进入多用户状态。
init读文件/etc/ttys,对每一个允许登录的终端设备,init拥有一次fork,它所生成的子进程则执行(exec)程序getty。
第二章unix的进程

(4)当前目录和当前根,描述进程的文件系统 环境。
(5)计时器域,记录进程及其后代在核心态和 用户态运行所用的时间。
(6)一些输人脑出参数,描述要传输的数据量, 在用户空间的源(或目的)数据的地址,文件 的输入输出偏移量等。
(7)限制域,指出进程的大小及它能“写”的 文件大小限制。
/*进程的运行状态*/ /*进程的标志域*/ /*进程的优先数*/ /*进程接收到的中断号*/ /*进程拥有者的用户ID*/ /*进程在内存中的驻留时间*/ /*进程的使用cpu时间*/ /*计算进程优先数的偏置量*/ /*控制终端*/ /*当前进程的进程ID */ /*当前进程父进程的进程ID*/ /*交换区的地址*/ /*进程文件的大小*/ /*进入睡眠的原因*/ /*指向文本区的指针*/
} proc[NPROC];
UNIX System V的进程表项
(1)标识进程状态的状态域。UNIX System V 中共有9个状态。
(2)若干用户标识号,简称UID或用户ID。这些 用户标识号指出该进程属于哪一用户,具有何种 特权,如是否可以互相发送救中断信号等。
(3)若干进程标识号,简称PID或进程ID,说明 进程间的相互关系。
int u_arg[5]; /*系统调用时传递的参数*/
int u_tsize; /*正文区的大小*/
int u_dsize; /*数据区的大小*/
int u_ssize; /*栈区的大小*/
int u_sep;
/*正文区分开存储的标志*/
int u_qsav[2]; /*当进程被中断时保存r5,r6*/
(4) 每个进程还有一组对应于实际硬件寄 存器的寄存器。系统中有许多活动进程,但只 有一组硬件寄存器。内核将当前运行进程的寄 存器组保存在硬件寄存器中,将其他进程的寄 存器组保存在每个进程的数据结构中。
UNIX系统开发-系统调用-进程间高级通信

UNIX系统开发-系统调用-进程间高级通信基本上所有的系统调用成功时返回0或正数,失败时返回负值。
消息通信每个消息队列都有一个msqid_ds类型的控制结构,该结构中包括对消息队列的访问权限,其数据结构如下:struct msqid_ds{struct ipc_perm msg_perm; /*操作权限结构*/struct msg msg_first; /*指向消息队列的第一个结构*/struct msg msg_last; /*指向消息队列的最后一个结构*/ushort msg_cbytes; /*队列中当前字节数*/ushort msg_qnum; /*队列中消息数*/ushort msg_qbytes; /*队列可容纳的最大字节数*/ushort msg_lspid; /*最后发送消息的进程号*/ushort msg_lrpid; /*最后接收消息的进程号*/ushort msg_stime; /*最后发送时间*/ushort msg_rtime; /*最后接收时间*/time_t msg_ctime; /*消息队列最后修改时间*/};msgget系统调用的格式#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key,msgflg)key_t key; /*消息队列关键字*/int msgflags; /*创建标志和访问方式(类似于文件访问权限)*/参数与功能说明:msgflg低9位类似于文件访问权限的低9位,其他位指明消息队列的建立方式:若指定的关键字消息队列不存在,msgflg&IPC_CREAT为真,则为他建立一个新的消息队列;msgflg&IPC_CREAT为假,返回-1。
若指定的关键字消息队列存在,则返回该消息队列的描述符。
若msgflg&IPC_CREAT&IPC_EXCL为真,若指定的关键字消息队列不存在,失败返回-1;否则正常返回。
【精品】UNIX高级环境编程PPT课件

可以让一个程序的源代码由多个文件组成 可以采用多种程序设计语言来共同完成一个
程序
查看目标文件的工具
nm: 可以查看目标文件输入、输出符号 objdump: 可以查看目标文件的各种内容
zuojie@gs2:~/temp$ nm a.o 00000000 T f 0000001b T main
Shell
应用软件
库函数 系统调用
内核
内核的结构
典型的Unix系统内核一般包含以下几个 部分
进程调度 内存管理 虚拟文件系统 网络接口 进程间通信
用户层的基本组成
用户层软件包括
各种库 shell 能进行有机组合的命令程序 图形系统 各种应用软件
用户操作界面——Shell
时钟时间 循环次数
288.64 103316352
72.75 12914544
Hale Waihona Puke 6.76 16143187.03 201789
6.86
25223
6.84
788
用于I/O的数据结构
操作系统使用了三种数据结构表示打开 的文件
1. 位于进程记录项中的打开文件描述表 其中有一个指向文件表项的指针
2. 内核为所有打开文件维持的一张文件表 文件状态标志 文件偏移量 指向文件v节点表项的指针
客户端工具:svn svn checkout ... svn update svn commit svn add ...
Unix基础
Unix操作系统的结构
广义的操作系统包含两个部分:内核和 用户层软件
内核运行在核心态,完成了计算机资源 管理的绝大部分工作
用户层软件通过系统调用和内核进行打 交道
int main(void) {
进程、线程与任务程序之间的关系

进程、线程与任务程序之间的关系1,Aplication ⼀个.apk包就可以称⼀个application,⼀般application会有很多Activity 或其他service组成。
2,task:完成⽤户的⼀个⽬的的所有activity 组成⼀个task.提到task就该提到task stack任务栈也有⼈叫活动栈。
Android系统⽤⼀个栈来记录⼀个任务,既然⼀个任务是由许多activity组成的,那栈⾥存的就是所有的 activity。
为什么需要记录呢?因为记录可以通过按back 键回到上⼀个activity.这也是为什么我们按back键可以回到上⼀个活动的原因。
那么什么时会开启⼀个新的任务呢?A)Notification 启动Activity会开启⼀个task,因为通过notification开启activity之后不需要返回到notification,所以需要开启⼀个新的task,这就是为什么我们在nofication⾥⾯启动⼀个Activity需要设置Intent的Flag为 Intent.FLAG_ACTIVITY_NEW_TASK.3,explicit intent 是明确指定启动哪个Activity,⽐如 Intent intent= new Intent(ActivityA.this, ActivityB.class).⽽implicit intent并不明确指定启动那个Activity,⽽是通过设置⼀些Intent Filter来让系统去帅选合适的activity来处理。
为什么需要分这两种Intent呢?我觉得好处有两个:第⼀,Activity 的重⽤,当⼀个Activity在其manifest⾥设置了许多intent filter,当发⽣了implicit intent时,系统就会去匹配这些filter,是否符合⽬标。
所以在设计Activity的时候就要考虑到是否重⽤问题,若需要重⽤就要设置 intent filter. 第⼆,Implicit intent可以让⽤户选择⾃⼰喜欢的Activity来处理。
《高级操作系统》2.第二章 Unix中的进程

第二章Unix中的进程§2.1引入原因和定义同一用户可运行多个PGM多个用户可运行同一个PGM国家——政府——公民CS ——OS ——进程为了描述多道程序在并发系统中的执行过程说明:1.多道VS并发多道是内存中同时存放多个并发运行的PGM并发是同一时间段多个PGM在内存运行过有单道并发和多道并发,多道效率高2.相互依赖和制约的关系(程序之间)example:PGM:(动态信息)1.硬件关联信息:寄存器、R0~R152.软件关联信息:PID,优先级,运行时间,资源3.虚拟地址进程是程序在一个数据集上的一次执行过程,是系统中资源分配和调度的独立单1.进程→动态(是一个“执行过程”)2.同一个PGM在不同的数据集上运行是不同的进程3.不同的PGM在同一个数据集上运行是不同的进程1个PGM→多个进程§2.2 Unix进程定义为图像的执行图像=存储器图像+CPU图像+打开文件状态+现行目录+……PCB:(1) proc 基本控制块不管进程是否运行都需要查询的信息(2) user 扩充控制块进程在运行过程中需要查询的信息文件:P1运行file:xxx xxx xxx xxxSUID=1→赋给进程P1U-UID第一个U:表示哪一个,数据结构中的proc还是userUID:表示effective UIDu-ruid——用户real UIDu-rgid——用户real GIDp-uid——用户UID通常(开始)的时候u-uid、p-uid、u-ruid是一样的。
运行过程中u-uid是要改的,运行过程中校验的UID;u-ruid是注册时使用的,固有的。
功能:如果P1执行PGM1的suid=1,则调用进程P1的u-uid被置成PGM1文件主的u-ruid。
example:f1执行时,要访问f2、f3,f2、f3的suid=1,用户才能访问f2、f3,user运行f1出题→回答→和标准答案比→评分→登分记分册文件主是老师(suid=1是老师的u-ruid)学生运行到“登分”时,老师的r-ruid赋给学生的u-uidproc:p-stat: 进程调度状态,p表示是proc数据结构的p-flag: 进程的特征,描述text是否常驻内存,是否允许调出,在还是不在内存p-pri: 进程的优先数,表示优先权的数值,优先数越小,权限越高p-uid:p-time: 进程在内/外存中的驻留时间p-cpu: 使用CPU的程度,已运行的时间/创建至今的时间p-nice: 初始优先数p-pid: 进程的ID号p-ppid: 父进程的ID号p-addr: 非常驻内存部分的首址p-size: 非常驻内存部分的大小p-wchan: 等待原因p-textp: 指向text结构的指针p-sig: 软中断号p-ttgp: 指向对应的tty(终端)结构,描述终端的信息I/O完后:进程调度时:查p-wchan,把p-stat改成ready,查p-pri看谁优先权高,p-flag是否在内存,p-size多大,如果内存不够放,就要陶汰其它的,就要查p-timeuser:u-uid: 用来检验是否有权限u-ruid: 用来检验是否有权限u-gid: 分组,用来区分特权/一般进程,如[20,150],前面0~19表示系统进程,后面表示成员号u-rgid:u-procp: 指向本进程的proc,p-addru-uisa[]: 虚实地址对照片u-uisd[]: 虚实地址对照片u-ofile[]: 打开文件表u-tsize: text长度u-dsize: data大小u-ssize: 用户栈大小text结构:x-daddr: 在磁盘交换区的首址(块号)x-caddr: 在内存交换区的首址x-size: text长度x-iptr: 指向所在文件的inode(index-node),inode: FCB,描述文件的x-count: 共享进程数x-ccount: 共享文本且图像在内存的进程数§2.3 存储管理分为:核心态、用户态一.核心态系统调用和调用子程序的区别:分给用户程序空间8页:二.用户栈说明:1.逻辑上分为三部分,依次是text、数据段、用户栈2.按整页分配3.用户栈从最后一页开始分配,而且从高地址到低地址分配功能:1. 调度时机:(1) 不可剥夺的:进程已完成;等待某事件;时间片到;需要和其它进程同步 互斥:在某一段时间只允许一个人用 同步:在互斥里要求更高的情况: 互斥+进入规则 (2) 可剥夺的:高优先权的进程进入就绪队列2. 调度算法:基于动态优先数(pri)的调度方法3. 具体操作(切换)(1) 保护现场(2) 恢复选中进程的现场 p-pri 当前调度的 p-usrpri 用户态下的pri当进程p 处于用户态时,p-pri=p-usrpri 不断计算nice p cpup usrpri p -⨯+-+=-2450 其中的“4”是加速因子,根据调度策略可变如果进入核心态,给p-pri 赋值;返回用户态时再恢复成p-usrpri睡眠时 [0, 49] 读disk p-pri=20队列:进程树:关机时回到$sheep logout创建进程:1.一般方法:……create(n, A)n: name A: ptr,指向起始数据(空间大小,运行时间等……)……2. Unix创建思想fork()父、进程共享同一段代码:if (fork() == 0){子进程执行代码}else{父进程执行代码}fork()给父进程返回值是子进程ID,给子进程返回值是0说明:1.fork()执行后,父/子进程体为2个实体,独立并发运行2.fork()返回以后,父/子进程分叉运行不同的程序代码if (fork() == 0){printf(“I’m child”);}else{ printf(“I’m parent”);}结果可能先打印父的,后打印子的;也可能先打印子的,后打印父的。
UNIX系统(一)进程管理

区的类型和大小 区的状态 区在物理存储器中的位置 引用计数 指向文件索引结点的指针
P324
本进程区表: 本进程区表: 系统为每个 进程配置一张。 进程配置一张。
区的起始虚地址 指向系统区表中对应的区 表项的指针 P325
核心通过查找进程区表和系统区表, 核心通过查找进程区表和系统区表,将区的逻辑 地址变为物理地址。 地址变为物理地址。这里使用两张表来实现地址映 是为了实现对区的共享。 射,是为了实现对区的共享。
fork系统调用的格式是: 系统调用的格式是: 系统调用的格式是 int fork() 核心为fork完成下列操作: 完成下列操作: 核心为 完成下列操作 1) 为新进程分配一进程表项和进程标识符 2) 检查同时运行的进程数目 3) 拷贝进程表项中的数据 4) 子进程继承父进程的所有文件 5) 为子进程创建进程上下文 6) 子进程执行 P327
消息队列头表 其每一表项作为一个消息队列的头结点。 其每一表项作为一个消息队列的头结点。 它包括如下内容: 它包括如下内容: 指向消息队列的队首及队尾的指针 队列中消息的数目 队列中消息数据的总字节数等
五、UNIX进程通信 进程通信 UNIX进程的同步和通信有多种方式: 进程的同步和通信有多种方式: 进程的同步和通信有多种方式 Sleep和wakeup同步工具 和 同步工具 信号(signals)机制 信号 机制 管道(pipes)机制 管道 机制 消息队列机制 共享存储器机制 信号量集机制
Sleep和wakeup同步工具 1. Sleep和wakeup同步工具 Sleep过程 过程——进程睡眠 进程睡眠 过程 Wakeup过程 过程——进程唤醒 过程 进程唤醒
对信号的处理: 对信号的处理: 正在执行的进程每隔一定时间就要检查有无软中 断信号到达。 断信号到达。 若有,则按预置的处理方式进行处理。 若有,则按预置的处理方式进行处理。 当处理方式值为1时 当处理方式值为 时,进程不做任何处理便立即 返回; 返回; 当处理方式值为0时 进程自我终止; 当处理方式值为 时,进程自我终止; 当其值为非0非 整数时 整数时, 当其值为非 非l整数时,系统从核心态转为用 户态的软中断处理程序(因为该程序是用户程序 因为该程序是用户程序, 户态的软中断处理程序 因为该程序是用户程序, 故应运行在用户态),处理完毕后,再返回到用 故应运行在用户态 ,处理完毕后, 户程序的断点。 户程序的断点。
Unix的进程管理

Unix的进程管理Unix是一种广泛应用于服务器和工作站的操作系统,它以其稳定性和可靠性而受到广泛的认可。
与其他操作系统不同,Unix在进程管理方面取得了很大的发展,使得其在多任务处理中表现出色。
本文将介绍Unix的进程管理,包括进程概述、进程状态、进程控制、并发和死锁等方面。
一、进程概述在Unix中,每个运行的程序都是一个进程。
一个进程拥有一定数量的资源,包括内存、CPU时间、文件和I/O设备等。
进程在系统中运行时会产生这些资源的使用情况,Unix系统会通过进程管理来对这些使用情况进行有效的管理。
Unix中的进程由进程标识符(PID)唯一标识,每个进程都有一个唯一的PID。
进程之间是独立的,它们彼此之间不能直接接触,除非通过系统调用进行交互。
每个进程都有自己的地址空间,其中包含了代码、数据段和堆栈等信息。
二、进程状态Unix中的进程可以处于不同的状态,包括运行态、就绪态、阻塞态和终止态。
运行态:正在运行的进程处于该状态,它使用CPU资源进行指令执行。
就绪态:已经准备好运行但尚未分配CPU资源的进程处于该状态。
这些进程等待系统将CPU资源分配给它们。
阻塞态:进程被阻塞,等待某个事件的发生,例如等待I/O完成或等待信号。
终止态:进程已经完成了它的工作并退出系统,或者由于错误或其他原因而被操作系统终止。
三、进程控制Unix中的进程通过系统调用来进行管理。
父进程可以创建和控制子进程,这些子进程可以再次创建新的子进程。
Unix系统支持多级进程树,每个进程都有一个父进程和多个子进程。
系统调用fork()可以用来创建子进程。
当一个进程调用fork()时,系统会复制它的地址空间信息并分配新的PID。
这样,父子进程将会拥有相同的代码空间和数据空间,但是在运行时各自独立。
接下来,子进程将执行exec()函数,将新的程序加载到内存中并运行。
父进程可以使用wait()函数等待子进程结束,同时可以使用kill()函数终止自己或其他进程。
unix环境高级编程之进程

unix环境⾼级编程之进程
每个进程都有⼀个⾮负整型表⽰的唯⼀进程ID。
但是进程ID是可重⽤的。
ID为0的进程通常是调度进程,也叫叫唤进程,该进程是内核的⼀部分。
进程1通常是init进程,在⾃举过程结束时由内核调⽤(/sbin/init中)。
附注 ^(* ̄(oo) ̄)^ :
c程序的存储空间布局:
1)正⽂段 2)初始化数据段 3)⾮初始化数据段 4)栈 5)堆
从图中可看到,未初始化数据段的内容并不存放在磁盘上的程序⽂件中。
因为:内核在程序开始运⾏前将它们都设置为0.需要存放在程序⽂件中的段只有正⽂和初始化数据段。
c语⾔对于存储器的操作函数:
1)malloc:分配指定字节数的存储区。
初始值不确定。
2)calloc:为指定数量具指定长度的对象分配存储空间。
该空间中的每⼀位都初始化为0.
3)realloc:更改以前分配区的长度(增减或减少)。
当增加长度时,可能需将以前分⽀区的内容移动到另⼀个⾜够⼤的区域,以便在尾端提供增加的存储区,⽽新增区的初始值则不确定。
《APUE》读书笔记—第九章进程关系

《APUE》读书笔记—第九章进程关系 本章看后给⼈似懂⾮懂的感觉,主要是不知道实际当中如何去使⽤。
通过前⾯⼏章的学习,每个进程都有⼀个⽗进程,当⼦进程终⽌时,⽗进程得到通知并取得⼦进程的退出状态。
先将本章基本的知识点总结如下,⽇后再看时候好好总结⼀下。
1、终端登录 介绍了有终端登录Unix系统的过程。
通过init进程读⽂件/etc/ttys,fork⼀个⼦进程调⽤exec执⾏getty程序进⾏登录,当⽤户输⼊完⽤户名后,getty的⼯作完成了,然后调⽤login程序,类似execle("/bin/login","login","-p",username,(char *)0,envp)。
2、⽹络登录 经由内核的⽹络接⼝驱动程序,使⽤伪终端驱动程序,BSD中由inetd进程等待⽹络连接。
具体过程为:inti进程调⽤⼀个shell,启动守护进程inetd,等待TCP/IP连接请求达到主机,当⼀个连接请求到达时,fork⼀个⼦进程进⾏执⾏相关程序。
3、进程组 每个进程除了拥有⼀个进程ID外,还属于⼀个进程组,进程组是⼀个或多个进程的集合,每个进程组有⼀个唯⼀的进程组ID,可以通过getpgrp函数获取。
每个进程组可以有⼀个组长进程,其进程组ID等于其进程ID。
组长进程可以创建⼀个进程组,创建改组中的进程。
通过setpgid函数添加⼀个现有的组或者创建⼀个新进程组。
4、会话 会话(session)是⼀个或者多个进程组的集合,通常是由shell的管道线将⼏个进程编程⼀组。
进程调⽤setsid函数创建⼀个新会话,getsid函数返回调⽤进程的会话⾸进程的进程组ID。
5、控制终端 ⼀个会话可以⽤⼀个控制终端;建⽴与控制终端连接的会话⾸进程称为控制进程;⼀个会话中的⼏个进程组可以分为前台进程组和后台进程组;⼀个会话中只有⼀个前台进程组,但可以有多个后台进程组;中断(Ctrl+C,SIGINT)、退出(Ctrl+/,SIGQUIT)和挂起(Ctrl+Z,SIGTSTP)字符产⽣的信号发送到前台进程组。
UNIX系统的进程系统分析.ppt

(a)指向proc结构的指针。标识出对应于该user结构 的proc结构;
(b)真正用户标识符(real user ID)。它是超级用户 分配给用户的标识符,以后每次用户登录进入系统时,均 需送入此标识符;
(c)有效用户标识符(effective user ID)。一般情 况下,它与真正用户标识符相同,但在其它用户允许的情 况下,可用系统调用setuid将它改变为其它用户标识符, 以获得对该用户的文件进行操作的权力;
UNIX系统将所有进程的proc结构组织到一起,形成 一个进程表,也称为proc数组,表中的每一个proc结构 是该数组的一个元素,成为该进程表的一个表目。进程表 中的proc结构数量是有限制的,在UNIX系统中最多允许 有50个。
2020/3/27
5
● UNIX系统的proc结构主要包括以下各项:
● 整个系统中的进程控制如图7-4所示。
2020/3/27
11
正文表的表项 ……
用户正文段
正文表(text 数组)
……
进程表的表项
进程数据区 ppda
用户数据段
用户地址空间
进程表(proc 数组) 常驻内存部分
非常驻内存部分
图 7-4 进程的组成
2020/3/27
12
●在UNIX系统中,每个进程都包括两部分:系统程序部 分和用户程序部分。
因为进程控制块中包含的信息量很大,所以占用的空间 也很大。为了节省进程控制块所占的内存空间,UNIX系 统把每个进程的进程控制块分为两部分:
2020/3/27
4
(a)常驻内存部分,称proc结构,该结构中包含着进程调 度时必须使用的一些主要信息;
(b)非常驻内存部分,称user结构,该结构登记了 进程 运行时才要用到的更多的信息,它可以随用户的程序和数 据在内存中换进换出。
Unix环境高级编程(十八)高级进程间通信

Unix环境⾼级编程(⼗⼋)⾼级进程间通信 本章主要介绍了基于STREAM的管道和UNIX域套接字,这些IPC可以在进程间传送打开⽂件描述符。
服务进程可以使⽤它们的打开⽂件描述符与指定的名字相关联,客户进程可以使⽤这些名字与服务器进程通信。
1、基于STREAMS的管道 STREAMS pipe是⼀个双向(全双⼯)管道,单个STREAMS管道就能向⽗、⼦进程提供双向的数据流。
如下图所⽰:下⾯采⽤STREAMS管道实现加法协同进程实例,程序如下:1 1 #include <stdio.h>2 2 #include <stdlib.h>3 3 #include <unistd.h>4 4 #include <errno.h>5 5 #include <string.h>6 6 #include <signal.h>7 78 8 #define MAXLINE 10249 910 10 static void sig_pipe(int signo)11 11 {12 12 printf("SIGPIPE caught\n");13 13 exit(1);14 14 }15 15 int s_pipe(int fd[2])16 16 {17 17 return pipe(fd);18 18 }19 19 int main()20 20 {21 21 int n;22 22 int fd[2];23 23 pid_t pid;24 24 char line[MAXLINE];25 2526 26 signal(SIGPIPE,sig_pipe);27 27 s_pipe(fd);28 28 if((pid = fork()) == -1)29 29 {30 30 perror("fork() error");31 31 exit(-1);32 32 }33 33 if(pid == 0) //⼦进程⽤fd[1]34 34 {35 35 close(fd[0]);36 36 dup2(fd[1],STDIN_FILENO);37 37 dup2(fd[1],STDOUT_FILENO);38 38 execl(".//add","add",(char *)0);39 39 exit(0);40 40 }41 41 else //⽗进程⽤fd[0]42 42 {43 43 close(fd[1]);44 44 while(fgets(line,MAXLINE,stdin) != NULL)45 45 {49 49 perror("write() error to pipe");50 50 exit(-1);51 51 }52 52 if((n =read(fd[0],line,MAXLINE)) < 0)53 53 {54 54 perror("read() error to pipe");55 55 exit(-1);56 56 }57 57 if(n==0)58 58 {59 59 printf("child close pipe\n");60 60 break;61 61 }62 62 line[n] = '\0';63 63 fputs(line,stdout);64 64 }65 65 exit(0);66 66 }67 67 }在APUE2 P469中这样讲:“solaris⽀持STREAMS管道,Linux的可选附加包也提供了STREAMS管道。
UNIX系统开发-系统调用-进程间通信

UNIX系统开发-系统调用-进程间通信基本上所有的系统调用成功时返回0或正数,失败时返回负值。
进程的用户标志号管理系统调用的格式#include <unistd.h>unsigned short getuid()unsigned short getgid()unsigned short geteuid()unsigned short getegid()int setuid(int uid)int setgid(int gid)int seteuid(int euid)int setegid(int egid)参数与功能说明:前四个系统调用返回进程的实际用户标志号,有效用户标志号,实际用户组标志号和有效组标志号。
这些调用总能成功。
setuid和setgid用于设置进程的实际用户(组)标志号和有效用户(组)标志号。
如果调用进程的有效用户标志号是超级用户标志号,则将调用进程的实际用户(组)标志号和有效用户(组)标志号设为uid和gid;如果调用进程的有效用户标志号不是超级用户标志号,但他的实际用户(组)标志号为uid(gid)时,则其有效用户(组)标志号设为uid或gid。
如果调用进程的有效用户标志号不是超级用户标志号,且他的实际用户(组)标志号不为uid(gid)时,则调用失败。
Seteuid和setegid与setuid,setgid类似,只不过只对有效用户(组)标志号起作用。
进程标志号管理系统调用的格式#include <sys/types.h>#include <unistd.h>int getpid()int getpgrp()int getppid()int setpgrp()int setsid()参数与功能说明:前三个系统调用分别返回进程的进程标志号,进程组标志号和其父进程标志号。
他们总能成功返回。
第四,五个调用设置进程组标志号,他将调用进程的进程组标志号改为调用进程的进程标志号,使其成为进程组首进程,并返回这一新的进程组标志号。