为进程创建新会话-----setsid()-举例,精灵进程

#include <unistd.h>
pid_t setsid(void);
    描述:如果调用该系统调用的进程不是其进程组的组长则会创建一个新的会话。调用进程将会称为新会话的组长,会话id和其pid一致。也成为新会话中新的进程组的组长,进程组的id和其pid保持一致。调用进程是新进程组和新会话中唯一的进程,新的会话将会脱离终端的控制。
    参数:无
    返回值:
        成功:调用进程的pid将会返回
        失败:-1被返回,errno被设置。

基于上述系统调用,我们可以将一个bash下的子进程变成一个精灵进程,使其不受终端控制。
在终端启动的进程,首先进程继承了终端的会话id和进程组id,其次进程继承了终端的文件描述符(STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO),所以使用setsid()仅能改变进程的会话id和进程组id,却不能删除其继承到的文件描述符。在这种情况下,如果原终端没有关闭,那么进程将会在终端里输出。这种影响需要被避免。所以称为精灵进程还需要对其文件描述符制空。
dup2
验证函数如下:

#include <fcntl.h>
using namespace std;
int main(int argc,char *argv[]){
        //用于存放转换成字符串形式的时间格式的缓存区
        char timeBuf[128] = {0};
        //指定时间
        time_t nowTime = time(NULL);
        strftime (timeBuf,sizeof(timeBuf),"%Y-%m-%d %H-%M-%S",localtime(&nowTime));
        cout << timeBuf << endl;
        getchar();
        pid_t pid = fork();
        if(pid)
                exit(0);
        setsid();
        /*
        int fd = open("/dev/null",O_RDWR,0);
        if(fd != -1){
                dup2(fd,STDIN_FILENO);
                dup2(fd,STDOUT_FILENO);
                dup2(fd,STDERR_FILENO);
                if(fd > STDERR_FILENO)
                close(fd);      
        }
        *
        */
        sleep(30);
        cout << "精灵进程a.out" << endl;
        sleep(60);
}

结论描述:
启动进程,观察a.out在进程树的位置,是终端的一个子进程,如下
启动进程时的pstree
敲击回车之后,执行了setsid(),手动退出启动进程的终端,观察a.out在进程树的位置,如下
脱离终端之后

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值