进程是正在运行的程序,是系统分配资源的单位。使用ps命令可以查看系统正在运行的进程。
1、创建进程fork()
fork()函数可以创建一个子进程。程序从调用fork时开始分叉为两个进程,因此fork函数返回两次,一次返回0,表示子进程正在运行,一次返回子进程的PID。当进程创建失败,返回-1
pid_t id; id=fork(); switch(id){ case 0: printf("son process is running "); break; case -1: printf("fork failed "); break; default: printf("father process is running "); }
vfork()函数同样得到一个子进程,但与fork完全复制父进程的资源不同,vfork共享父进程的资源。子进程的修改等同父进程对资源的修改。并且,fork后父子进程执行的先后顺序由系统调度决定,具有不确定性。而vfork确保子进程先运行,当子进程调用exec()或者exit()时父进程才开始运行。vfork系统开销小。
2、得到PID
getpid();//获得本进程ID getppid();//获得父进程ID
3、执行程序
pid_t id; id=fork(); //id=vfork(); switch(id){ case 0: printf("son process is running "); printf("my pid is %d, ppid is %d ",getpid(),getppid() ); execve("son",argv,environ); printf("never go here "); break; case -1: printf("fork failed "); break; default: printf("father process is running "); printf("my pid is %d, ppid is %d ",getpid(),getppid() ); } wait(NULL); exit(0);
使用exceve等函数可以在进程中调用可执行文件,从而使用新的程序替代当前的进程。调用exce族函数后,原进程便死亡,新程序代替原进程执行,但保留原进程的pid和ppid。
上面程序使用fork创建新进程,因此父子进程的调用顺序不确定。如父进程先比子进程结束,则子进程的ppid为1,代表子进程由init进程托管。如使用wait()函数则父进程将等待子进程结束。使用vfork则可保证子进程先运行。
wait()是等待第一个子进程结束。waitpid()可设定等待特定pid的子进程结束。
在父进程中新建一个子进程,然后令父进程结束,子进程在后台运行,这就是一个守护进程。
4、改变进程优先级
可通过设置进程的优先级来确保进程首先运行。shell中通过nice命令设置进程优先级。程序中使用setpriority()和getpriority()函数可得到和设置进程的优先级。