setsid命令以及会话与守护进程的概念

Linux 系统编程:深入理解进程组、会话与 `setsid` —— 守护进程的雏形 本文深入解析了Linux系统中的进程组(Process Group)和会话(Session)概念。通过命令行演示和代码实战,展示了进程组的创建与管理方法,重点讲解了如何利用setsid()函数创建新会话以开发守护进程。文章详细说明了进程间的层级关系,包括进程组与作业管理、会话与终端控制的关系,并通过示例代码演示了子进程如何脱离原有会话成为独立守护进程。最后总结了关键知识点,包括进程组管理、会话创建方法以及守护进程的特征,为Linux系统管理和后台服务开发提供了实用指导。 阅读详情
linux常用的命令
setsid命令的一般格式:
setsid();
说明:当进程是会话的领头进程时setsid()调用失败并返回(-1)。setsid()调用成功后,返回新的会话的ID,调用setsid函数的进程成为新的会话的领头进程,并与其父进程的会话组和 进程组脱离。由于会话对控制终端的独占性,进程同时与控制终端脱离。
pid_t pid = fork(); //fork a process
if (pid < 0) exit(0); //fork error
if (pid > 0) exit(0); //father process exit
setsid(); //creat a new session for a process
//之前parent和child运行在同一个session里,parent是会话(session)的领头进程,
//parent进程作为会话的领头进程,如果exit结束执行的话,那么子进程会成为孤儿进程,并被init收养。
//执行setsid()之后,child将重新获得一个新的会话(session)id。
//这时parent退出之后,将不会影响到child了。

进程组
  一个或多个进程的集合
  进程组ID: 正整数
  两个函数
  getpgid(0)=getpgrp()
eg:显示子进程与父进程的进程组id

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main() {
    pid_t pid;


    if ((pid=fork())<0) {
        printf("fork error!");
    }else if (pid==0) {
        printf("The child process PID is %d.\n",getpid());
        printf("The Group ID is %d.\n",getpgrp());
        printf("The Group ID is %d.\n",getpgid(0));
        printf("The Group ID is %d.\n",getpgid(getpid()));
        exit(0);
    }


    sleep(3);
    printf("The parent process PID is %d.\n",getpid());
    printf("The Group ID is %d.\n",getpgrp());


    return 0;
}

进程组id = 父进程id,即父进程为组长进程

组长进程
  组长进程标识: 其进程组ID==其进程ID
  组长进程可以创建一个进程组,创建该进程组中的进程,然后终止
  只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关
  进程组生存期: 进程组创建到最后一个进程离开(终止或转移到另一个进程组)
 
一个进程可以为 自己或子进程设置进程组ID
  setpgid()加入一个现有的进程组或创建一个新进程组

eg:父进程改变自身和子进程的组id

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main() {
    pid_t pid;


    if ((pid=fork())<0) {
        printf("fork error!");
        exit(1);
    }else if (pid==0) {
        printf("The child process PID is %d.\n",getpid());
        printf("The Group ID of child is %d.\n",getpgid(0)); // 返回组id
        sleep(5);
        printf("The Group ID of child is changed to %d.\n",getpgid(0));
        exit(0);
    }


    sleep(1);
    setpgid(pid,pid); // 改变子进程的组id为子进程本身
    
    sleep(5);
    printf("The parent process PID is %d.\n",getpid());
    printf("The parent of parent process PID is %d.\n",getppid());
    printf("The Group ID of parent is %d.\n",getpgid(0));
    setpgid(getpid(),getppid()); // 改变父进程的组id为父进程的父进程
    printf("The Group ID of parent is changed to %d.\n",getpgid(0));


    return 0;
}

 

 

会话: 一个或多个进程组的集合
  开始于用户登录
  终止与用户退出
  此期间所有进程都属于这个会话期

建立新会话:setsid()函数
  该调用进程是组长进程,则出错返回
    先调用fork, 父进程终止,子进程调用
  该调用进程不是组长进程,则创建一个新会话
    •该进程变成新会话首进程(session header)
    •该进程成为一个新进程组的组长进程。
    •该进程没有控制终端,如果之前有,则会被中断
组长进程不能成为新会话首进程,新会话首进程必定会成为组长进程...

会话ID:会话首进程的进程组ID
获取会话ID: getsid()函数

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main() {
    pid_t pid;


    if ((pid=fork())<0) {
        printf("fork error!");
        exit(1);
    }else if (pid==0) {
        printf("The child process PID is %d.\n",getpid());
        printf("The Group ID of child is %d.\n",getpgid(0));
        printf("The Session ID of child is %d.\n",getsid(0));
        sleep(10);
        setsid(); // 子进程非组长进程,故其成为新会话首进程,且成为组长进程。该进程组id即为会话进程
        printf("Changed:\n");
        printf("The child process PID is %d.\n",getpid());
        printf("The Group ID of child is %d.\n",getpgid(0));
        printf("The Session ID of child is %d.\n",getsid(0));
        sleep(20);
        exit(0);
    }


    return 0;
}

在子进程中调用setsid()后,子进程成为新会话首进程,且成为一个组长进程,其进程组id等于会话id

 

 

守护进程
  Linux大多数服务都是通过守护进程实现的,完成许多系统任务
  0: 调度进程,称为交换进程(swapper),内核一部分,系统进程
  1: init进程, 内核调用,负责内核启动后启动Linux系统
  没有终端限制
  让某个进程不因为用户、终端或者其他的变化而受到影响,那么就必须把这个进程变成一个守护进程
 
守护进程编程步骤
  1. 创建子进程,父进程退出
    • 所有工作在子进程中进行
    • 形式上脱离了控制终端
  2. 在子进程中创建新会话
    • setsid()函数
    • 使子进程完全独立出来,脱离控制
  3. 改变当前目录为根目录
    • chdir()函数
    • 防止占用可卸载的文件系统
    • 也可以换成其它路径
  4. 重设文件权限掩码
    • umask()函数
    • 防止继承的文件创建屏蔽字拒绝某些权限
    • 增加守护进程灵活性
  5. 关闭文件描述符
    • 继承的打开文件不会用到,浪费系统资源,无法卸载
    • getdtablesize()
    • 返回所在进程的文件描述符表的项数,即该进程打开的文件数目


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>


int main() {
    pid_t pid;
    int i,fd;
    char *buf="This is a daemon program.\n";


    if ((pid=fork())<0) {
        printf("fork error!");
        exit(1);
    }else if (pid>0)  // fork且退出父进程
        exit(0);
    
    setsid();    // 在子进程中创建新会话。
    chdir("/");  // 设置工作目录为根
    umask(0);    // 设置权限掩码
    for(i=0;i<getdtablesize();i++)  //getdtablesize返回子进程文件描述符表的项数
        close(i);                // 关闭这些不将用到的文件描述符


    while(1) {// 死循环表征它将一直运行
// 以读写方式打开"/tmp/daemon.log",返回的文件描述符赋给fd
        if ((fd=open("/tmp/daemon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0) {
            printf("Open file error!\n");
            exit(1);
        }
        // 将buf写到fd中
        write(fd,buf,strlen(buf)+1);
        close(fd);
        sleep(10);
        printf("Never output!\n");
    }


    return 0;
}

因为stdout被关掉了,所以“Never ouput!”不会输出。

查看/tmp/daemon.log,说明该程序一直在运行



linux之setsid命令 1 setsid命令 setsid主要是重新创建一个session,子进程从父进程继承了SessionID、进程组ID和打开的终端,子进程如果要脱离父进程,不受父进程控制,我们可以用这个setsid命令 2 测试 比如我们ping baidu.com setsid ping baidu.com 这个时候我们再ctrl+c终端,我们发现依然还是ping,说明... 阅读详情

相关推荐

modbus-esp8266库深度解析:工业级Modbus协议栈实现

Modbus是一种广泛应用于工业自动化领域的通用串行通信协议,其核心在于标准化的功能码、寄存器模型与帧结构设计。基于RTU、ASCII和TCP三种传输变体,Modbus协议通过主从架构实现设备间可靠数据交互,具备低开销、高兼容性与强实时性等技术价值。在边缘计算与工业物联网场景中,它被广泛用于PLC通信、传感器数据采集、HMI集成及远程固件升级(FOTA)等关键任务。针对ESP8266/ESP32等Wi-Fi微控制器平台,modbus-esp8266库提供了完整协议栈支持,涵盖多实例并发、回调驱动架构、零拷贝

weixin_42315569的博客 351

unistd.h中定义的setsid()与fork()

fork():是一个UNIX和类UNIX系统中的系统调用,用于创建一个新的进程,新进程是调用进程的子进程。1、创建新进程: fork() 用于创建一个新的进程,新进程是原进程的副本。需要注意的是,父进程和子进程之间并不共享内存,它们有各自的内存空间,因此在进程间通信时需要使用专门的IPC(进程间通信)机制,如管道、消息队列、共享内存等。3、分支执行: fork() 的典型用例是将一个进程分成两个分支,其中一个分支(子进程)可以执行不同的操作,而另一个分支(父进程)可以执行其他操作。1、它创建一个新的会话。

Artisan_w 999

【从零开始玩量化1】AKShare: Python开源财经数据接口库

文章目录量化的第一步:数据AKShare介绍AKShare安装AKShare使用AKTools安装/使用结语 量化的第一步:数据 想要玩量化,第一步要有数据,这个数据可能是历史交易数据、财务数据、宏观数据等等。我们最终要做的,无非就是从数据中分析出有价值的信息,以便用来指导投资策略。 在获取数据的这条道路上,我走了很多弯路,尝试了各种方法:使用Tushare到放弃、自己写网易股票页面的爬虫,自己写申万行业数据的爬虫、自己写同花顺问财的爬虫、使用聚宽的免费数据API等等,直到最终,我发现了AKShare。 A

量化投资助手的博客 5万+

setsid是什么命令

是一个 Linux/Unix 命令,它用于启动一个进程,并将其与当前会话分离。这意味着进程不再受当前终端的控制,即使会话被终止,该进程也会继续运行。命令通常用于在后台运行进程,并将其与终端分离,以确保即使终端关闭,进程也可以继续运行。

ihateright的博客 2061

oracle19c 无备份情况下重建ocr 和 votedisk

无备份情况下重建ocr 和 votedisk – 19c 备注:测试环境基本上都有ocr自动备份文件,建议参考有备份情况下恢复ocr和votedisk Deconfigure and reconfigure entire cluster will rebuild OCR and Voting Disk, user resources (database, instance, service, ...

fangang001的专栏 4182

C300 | 5680t | 新格林| AN5516 | 远程ONU升级指导

ONU的远程管理升级 1、ZTE C300 OLT : 1.1 环境拓扑: PC1(filezilla server)------(uplink_default-vlanID)OLT---------ONU | | mng1 1.2 配置部署: 1):PC1(filezilla server): IP:192.168.88.252 255.255.255.0 配置FTP-Server的用户名:gp...

Shelly的博客 3770

linux守护进程之setsid理解

linux进程管理 setsid

weixin_43412488的博客 6079

避坑指南:微信小程序蓝牙广播在iOS上的那些‘坑’(附serviceUuids传值解决方案)

本文深入解析微信小程序蓝牙广播在iOS平台上的开发难点,特别是`serviceUuids`传值解决方案。通过对比iOS与安卓的蓝牙协议实现差异,提供实战编码策略和硬件端配合方案,帮助开发者有效规避兼容性问题,提升蓝牙外围设备开发效率。

weixin_30316097的博客 423

setsid 命令介绍和使用案例

功能setsid创建一个新的会话,并将当前进程设置为该会话的首进程,使其脱离原有的终端控制。用途:常用于启动守护进程或在后台运行长时间执行的任务。setsid是一个非常有用的命令,能够在新的会话中启动进程,使其独立于终端运行。通过了解setsid的工作原理和使用示例,您可以有效地管理后台任务和守护进程,提高系统管理效率。

948

【华为OD机试真题】2、在字符串中找出连续最长的数字串含+-号 | 机试真题+思路参考+代码解析(C++、Java、Py)

题目描述 >请在一个字符串中找出连续最长的数字串,并返回这个数字串。 如果存在长度相同的连续数字串,返回最后一个。 如果没有符合条件的字符串,返回空字符串””。   注意: 数字串可以由数字”0-9″、小数点”.”、正负号”±”组成,长度包括组成数字串的所有符号。 “.”、“±”仅能出现一次,”.”的两边必须是数字,”±”仅能出现在开头且其后必须要有数字。 长度不定,可能含有空格

KJ.JK 6273

手把手教你学Simulink——基于Simulink的固态变压器(SST)多级协同控制

摘要:本文详细介绍了基于Simulink的固态变压器(SST)多级协同控制方法。SST作为新一代智能电网核心设备,通过AC-DC整流、DC-DC隔离和DC-AC逆变三级架构实现电能高效转换。针对多级耦合难题,提出能量-功率协同控制策略:纵向解耦电压环与功率前馈,横向联动级间功率指令。在Simulink中搭建10kV/400V系统模型,实现直流母线电压波动<2%的动态性能。特别设计了负载突变时的三级协同机制,通过虚拟惯性算法和前馈控制实现快速响应。文章包含完整的建模步骤、控制推导和参数设置,为电力电子工

MHD0815的博客 195

linux9.守护进程

01 概述 守护进程就是运行在后台的一种特殊进程,常见的守护进程包括系统日志进程syslogd、Web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。守护进程的名称通常以d结尾,如上,或:sshd、xinetd、crond等。 守护进程一般在系统启动时开始运行,除非强制终止,否则直到系统关机都保持运行;而且守护进程经常以root权限运行,因为它们要使用特殊的端口(1~1024)或访问某些特殊的资源。 守护进程的父进程是init进程,因为它真正的父进程在创建出子进程后就先于子进程退

笔记的博客 264

STM32 实现 4*4 矩阵键盘扫描(HAL库、标准库 都适用)

本文实现的代码是基于STM32HAL库的基础上的,不过标准库也可以用,只是调用的库函数不同,逻辑跟配置是一样的,按我这里的逻辑来配置即可。 1、键盘原理图: 原理举例:先把 F0-F7 内部拉高,这样这个8个引脚都是高电平,然后就进行列扫描。例如:假如按下3按钮,Y3 列扫描,把F4先拉低,然后读取F0-F3的状态,就会读出为1110,这就可 以知道是F3行拉低了,同时这时候是程序控制F4拉低的,这样就可以知道是F4列导致它转态变化了的,这样就可以定位出是F4列F3行的按键按下了;其他的列也是这样子扫描

lhh_qrsly的博客 7058

会话和守护进程

进程组,也称之为作业。 BSD 于 1980 年前后向 Unix 中增加的一个新特性。代表一个或多个进程的集合。每个进程都属于一个进程组。在 waitpid 函数和 kill 函数的参数中都曾使用到。操作系统设计的进程组的概念,是为了简化对多个进程的管理。当父进程,创建子进程的时候,默认子进程与父进程属于同一进程组。进程组 ID==第一个进程 ID(组长进程)。所以,组长进程标识:其进程组 ID==其进程 ID 。可以使用 kill -SIGKILL -进程组 ID(负的)来将整个进程组内的进程全部杀死 。

StudyWinter的博客 414

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

守护进程化

相信大家已经知道它的两个参数是什么意思了,和我们写的功能一样,只不过含义相反。但是我们一般不建议使用系统的。,因为不同系统的这个函数,默认行为可能有所差别,还是使用自己的比较稳妥,且这个接口实现起来也不麻烦。终端是“窗口”,提供交互界面;Bash是“大脑”,处理命令逻辑。系统也提供了将进程守护化的接口。

weixin_73870552的博客 726

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

setsid()

setsid ----------------------------------------------- setsid命令 linux常用的命令 setsid命令的一般格式: setsid(); 说明:当进程是会话组长时setsid()调用失败。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与

thinkinwm的专栏 1664

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

013会话和守护进程

Linux 会话和守护进程

m0_73604721的博客 335

一文让你真正理解 守护进程!!!

定义: 守护进程(Daemon Process)是指在后台运行的进程,它通常不与用户直接交互,而是为系统或其他程序提供服务。守护进程一般会在系统启动时启动,运行在后台,处理各种系统任务或服务请求,直到系统关闭。特点后台运行:守护进程通常不需要用户干预。它们在后台静默运行,进行必要的任务处理,比如文件清理、定时任务、网络服务等。不依赖终端:守护进程通常脱离终端,意味着它不会与任何终端相关联,不会占用用户的终端窗口。它们的标准输入、标准输出、标准错误都可能被重定向。无用户交互。

2402_83315537的博客 722

[Linux]----守护进程

这节课我来给大家讲解在Linux下如何让进程守护化,运行在后台,处理我们的任务.正文开始!守护进程也称为精灵进程(Daemon),是运行在后台的一种特殊进程.它独立于控制中断并且周期性的执行某种任务或者等待处理某些发生的事件.Linux系统启动是会启动很多服务清楚,这些系统服务进程没有控制终端,不能直接和用户交互.其他进程都是在用户登录或运行程序时创建.在运行结束或者用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直运行这.这种进程都有一个名称叫守护进程(Daemon).

拾至名瑰的博客 8929

浅谈守护进程

一、守护进程是什么? 守护进程:长时间在后台运行的程序,一般不跟用户进行交互,例如 Windows 上称为服务。

chang466477509的博客 548

Linux网络编程——守护进程

在我们上一篇TCP网络通信文章中,我们使用了守护线程,但是当时没有做过多的了解,下面再本文中,我们再做详细介绍。

学习日记 1332

守护进程

守护进程所谓守护进程就是7*24小时一直运行在服务器端不受登录、注销影响。也称精灵进程。 守护进程自成组自成会话。 这里有一点需要说明,后台作业并非守护进程,后台进程是指会话内部的作业,当关闭会话时会话内部所有后台作业都会结束而守护进程自成会话,所以不受影响。 **创建**一个守护进程需要调用setsid命令,但这条命令不能由该组组长调用,所以在创建后台进程时应先fork子进程,然后让子进程调用se

z517602658的博客 762

搞懂进程组、会话、控制终端关系,才能明白守护进程干嘛的?

守护进程 概念: 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程。周期性的执行某种任务或等待处理某些发生的事件。 Linux系统有很多守护进程,大多数服务都是用守护进程实现的。比如:像我们的tftp,samba,nfs等相关服务。 UNIX的守护进程一般都命名为*d的形式,如httpd,telnetd等等。 生命周期: 守护进程会长时间运行,常常在系统启动时就开始运行,直到系统关闭时才终止。 守护进程不依赖于终端 从终端开始运行的进程都会依附于这个终端,这个终端称为

胡图图 907

Linux - 进程间关系与守护进程

本文介绍了Linux系统中进程组、会话、控制终端和作业控制的相关概念。进程组包含多个进程,由组长进程管理;会话是进程组的集合,通过setsid函数创建;控制终端是Shell进程的输入输出接口。作业控制允许用户管理前后台任务,使用fg/bg命令切换作业状态,通过Ctrl+Z/C等信号控制作业。最后展示了如何将服务守护进程化,使其脱离终端独立运行。这些机制为Linux系统提供了强大的进程管理能力。希望这些内容对大家有所帮助,感谢大家的支持!

2402_84433929的博客 385

【Linux守护进程】二、守护进程详解

Linux守护进程专题二、守护进程详解。系统学习Linux开发、VIM/GCC/GDB/Make工具、Linux文件IO、进程管理、进程通信、多线程等,请关注专栏免费学习。

仅以此博客记录日常学习工作中所思所得,水平有限,难登大雅,万望海涵。 1380

【Linux】实现守护进程 | 以tcpServer为例

本文将以tcp服务器代码为基本,讲述如何将进程守护进程化,后台运行1.守护进程所谓守护进程,就是和其他进程没有关系的进程;其独立运行于系统后台,除非自己退出或收到信号终止,否则会一直运行下去1.1 进程组在我们使用的bash中,同一时刻只会有一个前台进程组如图,当一个前台进程开始运行之后,我们没有办法在当前终端开启第二个前...

weixin_32064437的博客 322
上一篇: sed删除行的一个问题
下一篇: select函数
行知2014
博客等级 码龄19年 8粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值