Unix中的进程
来源:互联网 发布:ed2k linux用什么下载 编辑:程序博客网 时间:2024/06/05 18:15
1:进程ID
每个进程都有一个非负整数表示的唯一进程ID。虽然是唯一的,但是进程ID可以重用。大多数Unix系统实现延迟重用算法。进程ID用pid_t表示。
一下两个函数用来得到当前进程和父进程的pid。
#include<unistd.h>pid_t getpid();//get pid of current processspid_t getppid();//get pid of parent process
2:创建新进程
#include<unistd.h>pid_t fork();fork函数被调用一次,但返回两次。子进程返回0,父进程返回子进程的进程ID。将子进程ID返回给父进程的理由是:因为一个进程的子进程可以有多个,并且没有一个函数可以得到一个进程的所有子进程的进程ID。fork使子进程得到返回值0的理由是:一个进程只有一个父进程,并且子进程可以通过getppid得到父进程的进程ID。
#include<unistd.h>#include<string.h>#include<stdio.h>#include<sys/wait.h>int glob=6;char buf[]="a write to stdout\n";void printErr(const char* info){ write(STDERR_FILENO,info,strlen(info)); _exit(1);}int main(){ int var=10; pid_t pid; if(write(STDOUT_FILENO,buf,strlen(buf))!=strlen(buf)) printErr("Write Error\n"); printf("pid=%d,before fork1\n",getpid()); if((pid=fork())<0)//括号不能少 printErr("fork error\n"); else if(pid==0){ glob++; var++; }else{ sleep(5); wait(NULL);//在wait返回前子进程是僵尸进程,返回后就不是僵尸进程了 printf("father after waitpid\n"); sleep(5); } printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var); return 0;}
编译后可执行文件为test1,在终端执行 ./test1,输出如下:a write to stdoutpid=5272,before fork1pid=5273,glob=7,var=11father after waitpidpid=5272,glob=6,var=10讲输出重定向到文件,./test1 >tmp.txt,然后显示文件cat tmp.txt,输出如下:a write to stdoutpid=5274,before fork1pid=5275,glob=7,var=11pid=5274,before fork1father after waitpidpid=5274,glob=6,var=10
可见重定向到文件后多数出了下面一行,是因为缓冲的缘故:write函数没有缓冲,因此只输出一行。标准I/O(printf)是有缓冲的,如果输出到终端设备是行缓冲的(由于有\n因此缓冲区被冲洗),在终端只输出一次。标准I/O输出到文件是全缓冲的,因此在在子进程的最后一行输出后会把缓冲区内的内容输出
pid=5274,before fork13:僵尸进程
当父进程fork之后创建了子进程后,如果子进程先结束,并且父进程没有wait或waitpid等待子进程,那么子进程变为僵尸进程,知道父进程结束才不是僵尸进程。
如果父进程先结束,那么子进程的父进程变为init进程。init进程的子进程结束后,init进程会调用一个wait函数取得其终止状态。
上面的程序子进程很快执行完毕,在父进程执行wait之前子进程变为僵尸进程,wait执行之后就不是僵尸进程了。可以使用下面的命令来查看当前的僵尸进程。
ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'
#include<sys/wait.h>pid_t wait(int * statloc);pid_t waitpid(pid_t pid,int* statloc,int options);两个函数返回值:若成功则返回进程ID,出错返回-1
僵尸进程的危害:僵尸进程是一个运行完毕的进程,所有的资源都已经释放了,包括打开的文件,占用的内存等等。但是仍然为其保留一定的信息(包括进程号,退出状态,运行时间等),直到父进程通过wait/waitpid来取时才释放。否则的话这些信息会一直保存,进程号就会被一直占用,但是系统所能使用的进程号是有限的,如果产生大量的僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。
解决僵尸进程的方法:如果一个进程fork一个子进程,但不要它等待子进程终止,也不希望子进程处于僵死状态知道父进程终止,实现这一要求的技巧是调用fork两次。
代码如下:
#include<unistd.h>#include<stdio.h>#include<string.h>#include<sys/wait.h>#include<stdlib.h>void printErr(const char* info){ write(STDERR_FILENO,info,strlen(info)); _exit(1);}int main(){ pid_t pid; if((pid=fork())<0) printErr("fork1 error\n"); else if(pid==0){ if((pid=fork())<0) printErr("fork2 error\n"); else if(pid>0){ printf("first child,pid=%d,ppid=%d\n",getpid(),getppid()); _exit(0); } sleep(1); printf("second child,pid=%d,ppid=%d\n",getpid(),getppid()); _exit(0); } if(waitpid(pid,NULL,0)!=pid) printErr("waitpid error\n"); printf("parent pid=%d\n",getpid()); return 0;}
- Unix中的进程
- Unix中的僵尸进程
- unix中的进程间通信
- UNIX中的进程通信(IPC)
- Unix/Linux进程在内存中的布局
- LINUX/UNIX中的进程层次中的shell登录过程
- unix进程
- Unix进程
- UNIX系统中的进程通信之共享内存
- Unix操作系统基础:Unix 进程
- 【操作系统】多处理机系统中的进程调度和Unix的进程调度
- Unix进程之进程概述
- UNIX多进程编程
- UNIX进程环境小结
- SCO UNIX 进程管理
- UNIX 进程揭秘
- UNIX 进程揭秘
- 转:UNIX 进程揭秘
- 解决mac下sublime text 2 无法读取cin,scanf的问题
- 字符串哈希函数
- 第8周项目6-本月有几天?
- xcode6 编译支持 i386 x86_64 arm7 arm7v arm64版本opencore-amr库
- 浅谈K-Means算法
- Unix中的进程
- CXF学习笔记(1)-HelloWorld!-发布webservice
- SQL语句解析(ST12和DB02的配合使用)
- 常用设备接口类GUID
- CXF学习笔记(2)-HelloWorld!-客户端调用
- HDU 1116 Play on Words
- Gas Station 加油站问题【oj】
- db2强制重启
- 选择爱人的数学方法(经典秘书问题)