Linux_进程控制

Linux进程模型
system用于调用shell,执行一条指定命令【在Linux下基本不用】

fork用于创建一个新的进程,该进程几乎是当前进程的一个完全拷贝

exec可以在进程中用另外的程序来替代当前运行的进程



进程标识符:
进程的属性PID(非零整数),父进程PPID

PID标示唯一的进程
所有进程的最‘老‘父进程就是init进程
//init进程是Linux内核启动后第一个执行的进程
-init引导系统,启动守护进程并且运行必要的程序

系统工作:
通电 -> 固话的代码[操作系统的引导]64k(自检CPU等硬件, 哪盘启动) -> 加载内核 -> 启动init(PID:1) -> 其他程序


PID常用用法就是创建唯一的文件或目录名,PID写入日志

头文件自己man

PID和PPID获取
unight int getpid();
unight int getppid();

每个用户都有一个UID,
getlogin函数返回执行程序的用户登录名,把登入名传给getpwnam函数,这个函数返回/etc/passed文件中该用户的相应信息

#include <pwd.h>
char *login = getlogin();//获得登入名
struct passwd *getpwnam(const char *name);//根据登入名获取信息


创建进程:
//在Linux下很少使用
int system("string");
//传递给/bin/sh -c 来执行string所指定的命令(cmd 下一样)

//如果没有找到/bin/sh返回127,如果出现其他错误返回-1,成功为0,但如果string为NULL,返回一个非零值
//如:
system("ls -l");


//在Linux下大量使用
pid_t fork(void);
//只克隆和自己一模一样的进程,有一些没继承[PID不一样]

成功先父进程放回子进程PID,向子进程返回0,调用fork一次,放回两次(一个在父进程,一个在子进程)

不能预期父进程是在它的子进程之前还是之后运行的,他们的执行是无序的,异步的
-- 异步的特性,意味着你不应该在子进程执行过于依赖父进程的代码,反之亦然
--fork也可能失败,超过允许它执行的最大进程数
--fork执行失败,向父进程放回-1,不在创建子进程

★根据返回值来判断是父进程还是子进程
//特别注意:
在调用fork后,子进程虽然继承了父进程的全部代码和内存,[但是子进程是从fork后才开始执行]
//fork分成两个进程,具有相同的内存和内存的值,在fork后独自运行

//例子
main{
printf("begin");
pid_t = fork();
if (pid_t == 0){
printf("我是子");}
else {
printf("我是父");
}
printf("end");
}
//打印结果
begin


end
end

 

//fork是使用:
服务器的服务程序,不依赖于控制台(与控制台脱离关系)后台程序,没有TTY的程序,
不同的进程中对同一个文件描述符进行操作(共享文件描述符)//继承了父进程的文件描述符

//fork
Unix用vfork来创建新进程,但是不产生父进程的副本.

execve
fork只能创建自己的产生新PID,完全独立的,两个进程都在
execve("path", 参数, NULL)//替代了调用它的进程,进程变成了调用的进程,资源都没变,改变了可执行的代码,只有一个进程
//注意:参数一定要符合main里的argv[]内的参数
如:
执行myFunc 1 2 argv[]里的参数是
myFunc 1 2


//这种用法较常用
★//fork后在把其中一个进程execve就使两个不同的进程共享同一个文件描述符,共享系统的资源
★//fork后把父进程exit(0),把子进程变成后台程序



wait和waitpid
//收集子进程的退出状态(释放资源),并且一直等待
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);//指定哪个子进程结束等待

status退出码:
WEXITSTATUS(status)//翻译退出码
//获得子进程退出return的值



//父进程一定要等子进程
//子进程可以不等父进程

父Kill子live(孤儿进程)
//子进程中的资源不是由创建它的父进程来释放的,而是由kernel(内核)来完成。
//当一个子进程的父进程退出后,init进程就会成为该子进程的父进程,当该子进程退出是init进程会调用wait来释放该子进程在进程表中占用的资源。
//父进程退出后,init收集退出状态

子Kill父live(可能出现僵尸进程)
父进程需要wait子进程,不wait子进程就成的僵死
//和内存泄漏相同,他是内核PID泄漏
//当父进程Kill,内核也会扫描子进程,释放


进程的终止:
主函数 return; 只能在主函数中退出 return 10;
调用exit(); 在子函数也能退出嗯 exit(10);
调用_exit;
调用abort函数; 异常退出,生成core文件,告诉OS程序出现错误,不产生退出码 abort()//是一种粗暴的调用,最后的手段来使用

//前4正常终止
信号终止 发送kill信号 kill(pid, SIGKILL)//向sig发送kill信号
//非正常的

--只要进程退出了,内核的处理都是相同的,关闭打开的文件,释放内存资源,和其他清理工作





_exit和exit的区别? (无内容)
_exit终止调用进程,但不关闭文件,不清除输出缓存,也不调用出口函数。
exit函数将终止调用进程。在退出程序之前,所有文件关闭,缓冲输出内容
将刷新定义,并调用所有已刷新的“出口函数”(由atexit定义)。
将刷新定义,并调用所有已刷新的“出口函数”(由atexit定义)。

 

 



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。