分类: LINUX
2013-12-17 23:33:39
原文地址:linux进程之多进程多状态 作者:guo443193911
一 return , exit , _exit
return : 用于函数返回,即结束一个函数
exit : 结束一个进程,并且刷新缓存
_exit : 结束一个进程,不刷新缓存
二 回收僵尸进程
僵尸进程:子进程结束,父进程没有对他进行收尸处理
pid_t wait(int *status);
功能:回收处于僵尸态的子进程
返回值:成功返回处于僵尸态子进程PID,失败返回-1
参数:获得子进程状态
int *p;
int status;
wait(p);错误,使用非法指针
wait(&status);正确
特点:
1.如果有子进程,但是没有处于僵尸态子进程,此时阻塞调用者
2.如果没有子进程,调用失败,返回-1
练习:
1.创建两个子进程,让子进程1,sleep(5),结束,子进程2一直运行
2.父进程回收僵尸态进程,并且判断子进程结束的原因,正常结束,输出返回值低8bit,非正常结束返回信号的序号
pid_t waitpid(int pid,int *status,int option);
功能:探测子进程的状态发生改变
返回值:成功返回状态发生改变的子进程PID,失败返回-1
状态改变:
R -> T(运行态->停止态)
T -> R(停止态—>运行态)
R -> z(运行态->僵尸态)
注意:如果没有指定option参数,即option = 0,只能探测僵尸态
pid:
1. 子进程PID,此时只探测指定的子进程
2. -1,探测所有的子进程
3. 0 探测和父进程同组的子进程
option:
1.WNOHANG 非阻塞调用(没有子进程状态发生改变的时候,不阻塞立即返回,返回0)
2.WUNTRACED 可以探测子进程从运行态->停止态
3.WCONTINUED 可以探测子进程从停止态->运行态
这写宏可以用"|"组合在一起使用
练习:(关心进程,调用方式,关心的状态 )
A.waitpid(pid,NULL,0);
B.waitpid(0,NULL,WNOHANG);
C.waitpid(-1,NULL,WNOHANG | WCONTINUED);
D.waitpid(-1,NULL,0);
E.waitpid(pid,status,WCONTINUED | WUNTRACED);
练习:
1.创建两个子进程,让子进程1,sleep(5),结束,子进程2一直运行
2.waitpid父进程回收僵尸态进程,并且判断子进程结束的原因,正常结束,输出返回值低8bit,非正常结束返回信号的序号
3.阻塞探测子进程1状态发生改变,(R->T,R->Z)
waitpid(pid1,&status,WUNTRACED);
4.非阻塞方式探测两个进程状态发生改变(R->T,T->R,R-Z)
waitpid(-1,&status,WNOHANG | WUNTRACED | WCONTINUED);
#include
#include
int main(int argc, const char *argv[])
{
int pid;
int status;
pid_t pid1,pid2;
if((pid1 = fork()) < 0)
{
perror("Fail to fork");
exit(EXIT_SUCCESS);
}
if(pid1 == 0)
{
printf("Child1 create PID:%d PPID:%d PGID:%d.\n",getpid(),getppid(),getpgrp());
sleep(3);
//独立成一个新组
setpgrp();
printf("Child1 create PID:%d PPID:%d PGID:%d.\n",getpid(),getppid(),getpgrp());
sleep(5);
printf("Child1 exit.\n");
exit(0x1234);
}
if(pid1 > 0)
{
if((pid2 = fork()) < 0)
{
perror("Fail to fork");
exit(EXIT_SUCCESS);
}
if(pid2 == 0)
{
printf("Child2 create PID:%d PPID:%d PGID:%d.\n",getpid(),getppid(),getpgrp());
while(1);
}
if(pid2 > 0)
{
printf("Parent PID:%d PPID:%d PGID:%d.\n",getpid(),getppid(),getpgrp());
while(1)
{
pid = waitpid(-pid1,&status,WNOHANG | WUNTRACED | WCONTINUED);
printf(" process status changed: %d.\n",pid);
sleep(1);
if(pid == 0)
{
continue;
}
//正常结束
if(WIFEXITED(status))
{
printf("Process over return least 8 bits : %#x.\n",WEXITSTATUS(status));
}
//非常结束
if(WIFSIGNALED(status))
{
printf("Process over Signal num : %d.\n",WTERMSIG(status));
}
//从运行到停止态
if(WIFSTOPPED(status))
{
printf("Process stooped : %d.\n",WSTOPSIG(status));
}
//从停止态到运行态
if(WIFCONTINUED(status))
{
printf("Process resumed.\n");
}
}
}
}
exit(EXIT_SUCCESS);
}
三 普通用户身份执行程序,进程拥有超级用户权限
进程的三个用户ID
RUID : 进程创建者
EUID : 进程访问权限
SUID : 保存EUID值
文件set-bit位,决定可执行文件在运行其进程拥有的权限
注意:
如果一个可执行文件的set-bit被设置,可执行文件在执行的时候,进程的EUID就是文件的所有者
chmod u+s file
操作步骤:
1.改变文件的所有者
sudo chown root file
2.打开set-bit位
sudo chmod u+s file