Linux系统编程——进程
进程状态
相关概念
- 进程ID:标识进程的唯一数字(父进程ID:PPID,启动进程的用户ID:UID)。
- 进程互斥:进程互斥指有若干个进程都要使用某一资源时,但该资源同一时刻最多允许一个进程使用,这时其他进程必须等待,直到占用该资源者释放该资源为止。
- 临界资源:操作系统中将同一时刻只允许一个进程访问的资源称为临界资源。
- 临界区:进程中访问临界资源的那段程序代码称为临界区。
- 进程同步:一组进程按一定顺序执行的过程称为进程间的同步。具有同步关系的这组进程称为合作进程。
- 进程调度:按照一定算法,从一组待运行的进程中选一个来占有CPU运行。(常见的调度算法:先来先服务,短进程优先调度,高优先级优先调度,时间片轮转法)
- 死锁:多个进程因竞争资源而形成一种僵局,导致这些进程都无法继续往前执行。
相关函数
getpid()
- 函数原型:
pid_t getpid(void);
- 头文件:
#include <sys/types.h>
#include <unistd.h>
- 函数功能:返回调用该函数的进程ID。
- 函数参数:无
- 返回值:调用该函数的进程ID
- 示例程序:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t id = 0;
id = getpid();
printf("process id is: %d\n", id);
return 0;
}
fork()
- 函数原型:
pid_t fork(void);
- 头文件:
#include <unistd.h>
- 函数功能: 创建一个子进程
- 函数参数: 无
- 返回值:
成功:在父进程中返回子进程的进程ID,在子进程中返回0
失败:返回-1,并且无新的子进程得到创建 - **备注:**fork()函数创建子进程之后,子进程的程序和父进程的程序相同,且从fork()函数之后运行。通过if()语句判断返回的ID可以使父进程和子进程做不同的事情。
- 示例程序:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
pid_t id;
if((id = fork()) > 0){
printf("process %d create sucess\n", id);
}else if(id == -1){
perror("process create error");
}
exit(0);
return 0;
}
vfork()
- 函数原型:
pid_t vfork(void);
- 头文件:
#include <sys/types.h>
#include <unistd.h>
- 函数功能: 创建一个子进程,并阻塞父进程
- 函数参数: 无
- 返回值:
成功:在父进程中返回子进程的进程ID,在子进程中返回0
失败:返回-1,并且无新的子进程得到创建 - 备注:调用fork()创建的子进程拥有自己独立的数据段和堆栈,但是vfork()创建的子进程共享父进程的数据段和堆栈。
- 示例程序:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
pid_t id;
if((id = vfork()) > 0){
printf("Process %d create success\n", id);
}else if(id == 0){
printf("Child process if running\n");
}else if(id == -1){
perror("process create error");
}
exit(0);
return 0;
}
/*
该程序先输出Child process is running,然后才输出Process XXX create success,可见vfork会阻塞父进程,先运行子进程
*/
exit()
- 函数原型:
void exit(int status);
- 头文件:
#include <unistd.h>
- 函数功能: 用来立刻结束目前进程的执行,并把参数status返回给父进程,并关闭未关闭的文件。此函数调用后不会返回,并会传递SIGCHLD信号给父进程,父进程可由wait函数取得子进程结束状态
- 备注: 父进程可以通过return结束,但是子进程只能通过exit()函数结束。
wait(),waitpid()
- 函数原型:
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
- 头文件:
#include <sys/types.h>
#include <sys/wait.h>
- 函数功能: 挂起调用该函数的进程,直到其某一个子进程结束
参数说明:
wstatus:用来记录子进程的退出状态,若不在意状态值,则该参数可设置为NULL。
pid:欲等待的子进程识别码
pid的值 意义 pid<-1 等待进程组识别码为pid绝对值的任何子进程 pid=-1 等待任何子进程,相当于wait() pid=0 等待进程组识别码与目前进程相同的任意子进程 pid>0 等待任何子进程识别码为pid的子进程 - option:option可以为0或下面的组合
option 意义 WNOHANG 没有任何已经结束的子进程则马上返回,不予等待 WUNTRACED 子进程进去暂停执行则马上返回,但结束状态不予理会 返回值:
成功:返回终止的那个子进程的ID
失败:返回-1
exec()
- 函数原型:
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
- 头文件:
#include <unistd.h>
- 函数功能: 在子进程中运行可执行文件
- 参数说明:
- path : 要运行的可执行文件的路径
- arg:arg为要运行的可执行文件的参数,直到以NULL来指明结束
- envp:传递给可执行文件的新环境变量数组
返回值:
成功:不返回
失败:返回-1,失败原因存放在errno中示例:
execl("/bin/ls","ls","/home",NULL);