一、
栈里面有:局部变量、形参、函数的返回地址
并发:多个任务同时运行
1.exit 库函数
退出状态,终止的进程会通知父进程,自己使如何终止的。如果是正常结束(终止),则由exit传入的参数。如果是异常终止,则有内核通知异常终止原因的状态。任何情况下,负进程都能使用wait,waitpid获得这个状态,以及资源的回收。
void exit(int status)
exit(1);
功能:让进程退出,并刷新缓存区
参数:status:进程退出的状态
返回值:缺省
EXIT_SUCCESS 0
EXIT_FAILURE 1
return 当该关键字出现在main函数中时候可以结束进程
如果在其他函数中则表示结束该函数。
exit -> 刷新缓存区 -> atexit注册的退出函数 -> _exit
2.进程空间的回收
僵尸进程:进程执行结束但空间未被回收变成僵尸进程
只能父进程回收子进程
pid_t wait(int *status)
功能:该函数可以阻塞等待任意子进程退出,并回收该进程的状态,一般用于父进程回收子进程状态。
阻塞的原因:对方还没有结束
3.waitpid(-1,status,0) = wait(status)
函数原型:pid_t waitpid(pid_t pid, int *status, int options);
阻塞模式和非阻塞模式---WNOHANG
4.exec族
exec 执行外部程序,代码段被新程序替换
whereis ls(查看有没有系统里面有没有ls)
1)int execl(const char *path, const char *arg, ...
/* (char *) NULL */);
2)int execlp(const char *file, const char *arg, ...
/* (char *) NULL */);
echo $PATH
3)int execv(const char *path, char *const argv[]);
4)int execvp(const char *file, char *const argv[]);
二、代码与例题
1.wait_status
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
pid_t pid = fork();
if(pid > 0)
{
printf("father %d\n", getpid());
int status;
pid_t ret = wait(&status);
if (WIFEXITED(status))
{
printf("son terminal normally, exit value %d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("son termnial by signal, signal value %d\n", WTERMSIG(status));
}
printf("pid : %d ret : %d\n", pid, ret);
}
else if (0 == pid)
{
int i = 10;
while(i--)
{
printf("son pid : %d\n", getpid());
sleep(1);
}
exit(20);
}
else
{
perror("fork");
return 1;
}
//system("pause");
return 0;
}
2.waitpid
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
pid_t pid = fork();
if(pid > 0)
{
printf("father %d\n", getpid());
int status;
while(1)
{
pid_t ret = waitpid(pid, &status, WNOHANG);
if(ret == pid)
{
if(WIFEXITED(status))
{
printf("child terminal normally, exit value %d\n ", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status)) //异常结束
{
printf("child terminal by signal , signal value %d\n ", WTERMSIG(status));
}
printf("pid %d ret %d\n", pid, ret);
break;
}
else if (0 == ret) //还没结束
{
printf("回收失败,稍后再试\n");
}
else
{
printf("回收错误\n");
return 1;
}
}
}
else if (0 == pid)
{
int i = 10;
while (i--)
{
printf("pid:%d child\n", getpid());
sleep(1);
}
exit(20);
}
else
{
perror("fork");
return 1;
}
// system("pause");
return 0;
}
3.exec族
#include
#include
int main(int argc, char **argv)
{
//execl("/usr/bin/firefox", "firefox","www.baidu.com",NULL);
//ls -a -l
//execl("/bin/ls", "ls","-a","-l",NULL);
//execlp("firefox", "firefox","www.baidu.com",NULL);
//execl("b.out", "./b.out",NULL);
//execlp("./b.out", "b.out", NULL);
char *args[] = {"ls","-l","-a","--color=auto",NULL};
char *args1[] = {"./b.out",NULL};
//execvp(args[0], args);
//execv("/bin/ls", args);
execv(args1[0], args1);
return 0;
}