Linux 终端-进程组-会话-守护进程

Linux 终端-进程组-会话-守护进程

- 终端

1>ctrl+alt+(1-6)文字终端,7是图形终端
文字终端(bash)的启动流程
在这里插入图片描述

- 网络终端

在这里插入图片描述

- 进程组(作业)

1>进程组ID=第一个进程ID(组长ID)
2>kill -SIGKILL -进程组ID(负的) //杀死进程组内的全部进程
3>进程组生命周期:进程组创建到最后一个进程结束(注意:组长进程结束,该进程并不会结束)
4>进程组操作函数

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
	/*******************************************************
	*函数1:getpgrp() 
	*头文件:#include <unistd.h>
	*格式:pid_t getpgrp(void);//无形参
	*作用:获取当前进程组ID
	*返回值:The POSIX.1 getpgrp() always returns the PGID of the caller.
	*********************************************************
	*函数2:getpgid() 
	*头文件:#include <unistd.h>
	*格式:pid_t getpgid(pid_t pid);//有参数:参数传0时,相当于getpgrp();
	*作用:获取指定进程组ID
	*返回值:getpgid(), and the BSD-specific getpgrp() return  a  process  group  on success.  On error, -1 is returned, and errno is set appropriately.
	*********************************************************
	*函数3:setpgid() 
	*头文件:#include <unistd.h>
	*格式: int setpgid(pid_t pid, pid_t pgid);//参数1:要改变默认所属进程组的进程;参数2:要加入或则要创建的进程.
	*作用:将参数1进程加入到参数2进程组中,通常是改变默认所属进程组,达到加入其他进程组或则创建一个新的进程组
	*返回值:成功-0;失败--1;
	*注意:1>如果子进程要创建新的进程组需要在fork()函数与execxx()函数之间(因为execxx()函数无返回值)
	*	  2>非root进程只能改变自己创建的子进程和有权操作的进程.
	*         3>getpid();getppid();
	*********************************************************/
int main()
{	
	pid_t pid =fork();
	if(pid==-1)
	{
		perror("fork");
		exit(1);
	}
	if(pid>0)
	{
		printf("parent process group ID:%d\n",getpgid(0));
		sleep(1);
		setpgid(pid,pid); //改变子进程进程组ID为自己的ID
		sleep(3);
		wait(NULL);
	}
	else{
		printf("child process ID:%d\n",getpid());
		printf("child process group ID:%d\n",getpgrp());
		sleep(2);
		printf("child process new group ID:%d\n",getpgrp());
	}
	return 0;
}

运行结果:在这里插入图片描述

- 会话(session)

1>进程组合在一起叫进程组,进程组组合在一起叫会话;
在这里插入图片描述组长进程不能成为新会话首进程,但会话首进程移动成为组长进程.

2>函数

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
/*******************************************************
*函数1:getsid() 
*头文件:#include <unistd.h>
*格式:pid_t getsid(pid_t pid);//pid=0:获取当前进程的会话ID,!=0:获取指定进程的会话ID;
*作用:获取当前进程所属的会话ID
*返回值:成功-会话ID,失败--1;
*********************************************************
*函数2:setsid() 
*头文件:#include <unistd.h>
*格式:pid_t setsid(void);
*作用:创建新的会话,并以自己ID为新的会话ID和组ID;
*返回值:成功-新的会话ID,失败--1;
*********************************************************/
int main()
{	
	pid_t pid =fork();
	if(pid==-1)
	{
		perror("fork");
		exit(1);
	}
	//不能用父进程创建会话
	if(pid==0)
	{
		//打印当前的各个ID
		printf("child process session ID:%d\n",getsid(0));//获取当前进程的会话id
		printf("child process  ID:%d\n",getpid());
		printf("child process group ID:%d\n",getpgid(0));//获取当前进程的组id
		if(setsid()==-1)//设置新的会话ID
		{
			perror("setsid error");
			exit(1);//exit(0)正常退出
		}
		printf("********************child process  session ID changed*******************\n");
		//打印新的的各个ID
		printf("child process session ID:%d\n",getsid(0));
		printf("child process  ID:%d\n",getpid());
		printf("child process group ID:%d\n",getpgid(0));
	}
	return 0;
}

运行结果:在这里插入图片描述

- 守护进程(daemon)

1>后台服务进程,一般以d结尾:eg:vsftpd httpd sshd xinetd等.
2>没有终端,不能直接交互(也就不需要文件描述符0\1\2)不受用户登录\注销的影响一直在运行.
3>创建守护进程(关键是创建会话)
在这里插入图片描述

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
	pid_t pid;
	//1步创建子进程
	if((pid=fork())==-1)
	{
		perror("fork error");
		exit(1);
	}
	if(pid>0)
	return 0;
	//子进程
	else{
	//2步:创建新会话
	 setsid();
	//3步:改变进程的工作目录
	if(chdir("/home/khy/"))//要检查返回值,此函数容易出错
	{
		perror("chdir error");
		exit(1);
	}
	//4步:指定文件掩码
	umask(0002);//文件创建的权限一般为775,所以掩码取002,第一个零表示八进制.
	//5步:关闭文件描述符0/1/2;或则重定向到/dev/null下面(收垃圾的)
	close(STDIN_FILENO);
	open("/dev/null");//此时文件描述符为0,就小原则.
	dup2(0,STDOUT_FILENO);
	dup2(0,STDERR_FILENO);
	//6步:守护进程逻辑,一直执行,用while()实现.
	while(1)
	{
	//因为守护进程没有终端,且不会应为用户登录注销影响(开机会影响),
	//所以想要开机就启动就要把它加入.bashrc里面或则init里面,开机启动.
	//7步:退出
	//这里一般要捕捉一个信号,来杀死自己.
	}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值