Linux环境:C编程多进程操作
进程基础知识
进程是程序与数据的结合,即运行中的程序。每个进程的所有状态信息保存在各自的进程控制块(PCB)中
进程标识
每个进程都有一个唯一的进程标识号pid,pid是一个整型变量。
同时每个进程都有 一个父进程标识号ppid来记录其父进程。
Linux系统中,init
进程是所有其他进程的祖先进程,init进程没有父进程,其pid=1,ppid=0
,
通过函数pid_t getpid(void) , pid_t getppid(void)
可以获得当前进程的pid
和ppid
进程运行身份
进程运行时需要对数据进行读写,而为了检查进程是否有读写文件的权限,需要通过进程的用户 ID 和组 ID来确认进程的访问权限。
进程的用户ID和用户组ID分为真实ID和有效ID。
- 真实ID是启动进程的用户ID和其组ID,可以通过函数
uid_t getuid(void)
和uid_t getgid(void)
获得 - 有效ID是内核对进程的访问权限检查时实际检查的ID,缺省状态下等同于真实ID。可以通过对可执行文件的权限设定,使得有效ID与真实ID不同。可以通过函数
uid_t geteuid(void)
和uid_t getegid(void)
获得
应用:
现有文件权限755的可执行文件1c.exe
可以对root用户目录下文件进行读写,所有者为root用户。
当使用普通用户执行1c.exe
时,有效用户ID为普通用户,所以没有权限访问root用户的文件。
此时可以将1c.exe
文件的可执行参数改为s,使用chmod 4755 1c.exe
或chmod u+s 1c.exe
命令,之后再使用普通用户执行1c.exe
时,可以正常读写root用户的文件。
这就是s参数的作用,可以使可执行文件执行时产生的进程的有效用户ID变为可执行文件的所有者,从而固定了该可执行文件对应进程的访问权限。
Linux下进程管理命令
常用进程管理命令:
命令 | 含义 | 常用参数 |
---|---|---|
ps | 查看系统中的进程 | -e 显示所有程序;-l 采用详细的格式来显示程序状况;-f 显示UID,PPIP,C与STIME栏位;-aux 查看%cpu(cpu 使用量) %mem(内存使用量)进程状态 |
top | 动态显示系统中的进程 | d<间隔秒数> 设置top监控程序执行状况的间隔时间,单位以秒计算 ;c 显示每个程序的完整指令,包括指令名称,路径和参数等相关信息;n<执行次数> 设置监控信息的更新次数 |
nice | 改变程序执行优先级 | -n<优先等级> 或-<优先等级> 或--adjustment=<优先等级> 设置欲执行的指令的优先权等级,等级的范围从-20-19,其中-20最高,19最低,只有系统管理者可以设置负数的等级 |
kill | 给程序发信号。缺省信号为SIGTERM(15),可将指定程序终止 | -l <信息编号> 若不加<信息编号>选项,则-l 参数会列出全部的信息名称;-s <信息名称或编号> 指定要送出的信息。 |
bp | 将程序放到后台运行 | 也可以通过在指令后添加& 直接把任务转入后台 |
fg | 将后台任务转到前台执行 | —— |
创建进程:四类函数
标准C函数system
函数原型:
int system(const char *string)
特点:
- system 函数通过调用 shell 程序/bin/sh –c 来执行 string 所指定的命令。
- 通过 system 创建子进程后,原进程和子进程各自运行,相互间关联较少
- system 调用成功,将返回 0,创建进程失败返回0
- system函数后面的参数还可以是一个可执行程序,通过加&可以使该程序后台运行
Linux C 接口fork
函数
函数原型:
pid_t fork(void)
函数原理:
fork
函数执行后创建一份当前进程的复制作为当前进程的子进程,子进程的进程空间与父进程一致,拥有的资源相同,只有进程号,计时器,和进程对资源的取用操作不同。通过判断fork函数的返回值可以判断是子进程还是父进程。
如果返回值是0则是子进程,大于0则是父进程,且返回值是子进程的进程号。如果返回负值则表示创建子进程失败。
示例程序:
int main()
{
int pid &