首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Linux:如何将文件描述符标记为在fork上不可继承?

在Linux系统中,当你使用fork()创建一个新进程时,你可能希望在新进程中不继承某些文件描述符。为了实现这一点,你可以使用文件描述符标记。

以下是如何将文件描述符标记为在fork上不可继承的步骤:

  1. 包含所需的头文件:#include <fcntl.h> #include <unistd.h>
  2. 在fork之前,使用fcntl函数将文件描述符标记为不可继承:int flags = fcntl(fd, F_GETFD); if (flags == -1) { // 错误处理 } flags |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, flags) == -1) { // 错误处理 }

这里,fd是你要标记的文件描述符,FD_CLOEXEC标志会使得在fork之后,新进程中的文件描述符不会继承这个标志。

  1. 现在,你可以继续执行fork操作:pid_t pid = fork(); if (pid == -1) { // 错误处理 } else if (pid == 0) { // 子进程代码 } else { // 父进程代码 }

通过这种方式,你可以确保在新进程中,标记为不可继承的文件描述符不会被继承。

推荐的腾讯云相关产品:

  • 腾讯云云服务器:提供可靠的云计算服务,帮助用户轻松处理各种应用场景的计算需求。
  • 腾讯云容器服务:支持弹性伸缩、自动扩展和自动恢复等功能,帮助用户快速构建、运行和管理容器化应用。
  • 腾讯云虚拟化:提供虚拟化技术,实现资源的高效利用和快速部署。

产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

IO多路复用之EPOLL

这是因为,假如没有设置EPOLL_CLOEXEC标志的fork将把描述符复制到子进程中的epoll实例,当这些进程中的某一个或者多个进程关闭了其中一个文件描述符,那么可能会导致程序的不可用,或者不在我们的预期之内...该表有两个字段: 控制文件描述符操作的标志(唯一的标志是exec关闭标志) 指向基础内核数据结构的指针 文件描述符可以通过系统调用(例如open,pipe,socket等)显式创建,也可以在派生期间从父进程继承...描述符也与dup / dup2系统调用“复制”。 文件描述符在满足如下几个条件之一时候,会被释放: 进程退出 调用close函数 fork一个进程时,子进程中的所有描述符都“复制”。 ...但是由于描述符3被标记为“执行时关闭”,因此在进程B执行之前,该描述符将被标记为“无效”,并且进程B将无法再访问它。...如果进程A然后分叉进程B,并且fd3被标记为close on exec标志,那么子进程B将继承父进程A的所有描述符,但不能使用fd3。

1.5K31

IO多路复用之EPOLL

这是因为,假如没有设置EPOLL_CLOEXEC标志的fork将把描述符复制到子进程中的epoll实例,当这些进程中的某一个或者多个进程关闭了其中一个文件描述符,那么可能会导致程序的不可用,或者不在我们的预期之内...该表有两个字段: 控制文件描述符操作的标志(唯一的标志是exec关闭标志) 指向基础内核数据结构的指针 文件描述符可以通过系统调用(例如open,pipe,socket等)显式创建,也可以在派生期间从父进程继承...描述符也与dup / dup2系统调用“复制”。 ? 文件描述符在满足如下几个条件之一时候,会被释放: 进程退出 调用close函数 fork一个进程时,子进程中的所有描述符都“复制”。...但是由于描述符3被标记为“执行时关闭”,因此在进程B执行之前,该描述符将被标记为“无效”,并且进程B将无法再访问它。 ?...如果进程A然后分叉进程B,并且fd3被标记为close on exec标志,那么子进程B将继承父进程A的所有描述符,但不能使用fd3。

87921
  • Python实现守护进程

    文件描述符 Linux是“一切皆文件”,文件描述符是内核为已打开的文件所创建的索引,通常是非负整数。进程通过文件描述符执行IO操作。...每个进程有自己的文件描述符表,因此相同的描述符可能指向同一个文件,也可能指向不同文件;来自不同进程的不同的描述符,当然也有可能指向同一个文件。...umask权限掩码 我们知道,在Linux中,任何一个文件都有读(read)、写(write)和执行(execute)的三种使用权限。其中,读的权限用数字4代表,写权限是2,执行权限是1。...已经是会话组长的进程,不可以再调用setsid()方法创建会话。因此,上面代码中,子进程可以调用setsid(),而父进程不能,因为它本身就是会话组长。...3、守护进程改变了会话、进程组、工作目录和文件描述符,后台进程直接继承父进程(shell)的 换句话说:守护进程就是默默地奋斗打拼的有为青年,而后台进程是默默继承老爸资产的富二代。

    2K80

    Python 守护进程

    我们不知     道我们继承了什么样的umask。     [这一步是可选的](译者注:这里指步骤5,因为守护程序不一定需要写文件) 6....调用‘close()’关闭文件描述符0,1和2。这样我们释放了从父进程继承的标     准输入,标准输出,和标准错误输出。...如果你认为有可能有打开的文件描     述符,你需要关闭它们,因为系统有一个同时打开文件数的限制。 7. 为标准输入,标准输出和标准错误输出建立新的文件描述符。...准确操作这些描述符是基于各自     爱好;比如说,如果你有一个日志文件,你可能希望把它作为标准输出和标     准错误输出打开,而把‘/dev/null’作为标准输入打开;作为替代方法...(译者注:一     般使用dup2函数原子化关闭和复制文件描述符。

    93530

    从进程组、会话、终端的概念深入理解守护进程

    这个步骤主要是要与继承父进程的会话、进程组、终端脱离关系。 3、禁止子进程重新打开终端 此刻子进程是会话组长,为了防止子进程重新打开终端,再次 fork 后退出父进程,也就是此子进程。...5、设置文件权限掩码 文件权限掩码是指屏蔽掉文件权限中的对应位。由于使用 fork()函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。...因此,把文件权限掩码设置为 0,可以大大增强该守护进程的灵活性。通常使用方法是umask(0)。 6、关闭文件描述符 子进程会继承已经打开的文件,它们占用系统资源,且可能导致所在文件系统无法卸载。...syslog 是 Linux 中的系统日志管理服务,通过守护进程 syslogd 来维护。该守护进程在启动时会读一个配置文件/etc/syslog.conf。该文件决定了不同种类的消息会发送向何处。..."/")) < 0) // 第4步 { syslog(LOG_ERR, "%s\n", "chdir"); exit(-1); } umask(0); // 第5步 // 第6步:关闭继承的文件描述符

    1.1K20

    如何创建多进程程序?(文末福利)

    另一种最常见的就是执行一个不同的程序,例如我们在shell终端执行一条命令,实际上就是bash(或者其他)调用fork之后,在执行exec族函数。...REG , test.txt lsof命令的用法可以参考《如何查看linux中文件打开情况?》...试想以下两点: 父子进程对同一个文件进行写,将共享文件偏移 如果该描述符是一个socket描述符,父进程退出后,子进程仍然打开着,父进程再次启动,将会出现端口被占用的问题。...所以如果父子进程的其中一个使用了fclose关闭了文件描述符,实际上还有另外一个进程打开了test.txt文件。...fork之后的返回值不同,进程ID也不同 子进程未处理信号设置为空 子进程不继承父进程设置的文件锁 一般子进程会执行与父进程不完全一样的代码流程 … 总结 fork用于创建进程,但是需要注意的是,子进程继承了很多父进程的东西

    1.7K20

    深拷贝与浅拷贝以及写时拷贝

    在大多数情况下,这样做常常是毫无意义的,因为许多子进程通过装入一个新的程序开始它们的执行,这样就完全丢弃了所继承的地址空间。...Linux的fork()使用写时复制 传统的fork()系统调用直接把所有的资源复制给新创建的进程。这种实现过于简单并且效率低下,因为它拷贝的数据或许可以共享。...也就是说,资源的复制是在需要写入的时候才会进行,在此之前,只有以只读方式共享。这种技术使地址空间上的页的拷贝被推迟到实际发生写入的时候。...在页根本不会被写入的情况下—例如,fork()后立即执行exec(),地址空间就无需被复制了。fork()的实际开销就是复制父进程的页表以及给子进程创建一个进程描述符。...COW技术初窥: 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时

    66420

    13(守护进程)

    13.2 守护进程的特征 守护进程是一种纯粹的后台进程,与运行前环境完全隔离,包括未关闭的文件描述符、控制终端、会话、进程组、工作目录以及文件创建掩码等 很多守护进程是父进程 fork 产生...,所以会继承所有的父进程地址空间中的环境,所以必须在守护进程诞生之初,断绝这些相关环境,当然,守护进程也可以在 linux 系统启动时从启动脚本 /etc/rc.d 中启动,也可以由 crontab 启动...事实上,守护进程与普通进程的编写并没有特别大的区别 13.3 编程规则 (1)进程从创建他的父进程那里继承了文件创建掩码,它可能会修改守护进程创建的文件的存取位。...调用int chdir (const char *path); (5)关闭打开的文件描述符。进程从创建它的父进程那里继承了打开的文件描述符,如不关闭,将会浪费系统资源。...可以通过open_max()和getrlimit()来判断最高文件描述符值,并关闭直到该值的所有文件描述符。

    80110

    守护进程

    一、Call fork and have the parent exit.--创建子进程,父进程退出。 这一步的作用有两个: 1.非系统守护进程可能是由用户手动执行的,比如在终端shell上执行....--设置文件屏蔽字。 这一步的作用有三个: 1.修改从父进程继承来的文件屏蔽字,避免父进程原先设置的文件屏蔽字对守护进程来说不合理。...--关闭不必要的文件描述符。 这一步同样可有可无,如果守护进程觉得有必要,可以这样做。如果确信没有从父进程继承什么文件描述符,或者需要这些继承的文件描述符,就不需要关闭。...} 注意 有很多守护进程的实现是两次调用fork,这样做主要是为了避免僵尸进程的产生。 何为僵尸进程呢? linux里的进程都属于一棵树,树的根结点是init(pid为1)。...是不是需要两次fork主要是看自己设计,上面nginx就没有两次fork,因为设计上很明确,父进程创建守护进程后就立刻退出了,不会存在僵尸进程的问题。

    2.8K40

    Python创建daemon

    参考《Linux/Unix 系统编程手册》     变成daemon,一个程序需要完成以下步骤:     1、执行一个fork(),父进程退出,子进程继续执行。...open() 调用中指定O_NOCTTY标记;       2、在setsid()调用之后执行第二个fork(),再次让父进程退出并让孙子进程继续执行,(这样确保了子进程不会成为会话组长,进程永远不会重新请求一个控制终端...,如:cron会将自身放在/var/spool/cron 目录下)     6、关闭daemon从父进程继承而来的所有打开着的文件描述符(由于daemon失去了控制终端,对0,1,2描述符完全可以关闭;...无法卸载长时间运行的daemon打开的文件所在的文件系统----文件描述符是一种有限资源)     7、关闭0,1,2文件描述符后,daemon通常会打开/dev/null,并让所有描述符都指向该设备...    --这样确保了当daemon调用在这些文件描述符上执行IO的库函数时不会出乎意料的失败; 实例: import sys,os,time def main():     """ A demo daemon

    77610

    如何让程序真正地在后台运行?

    同样的,其工作目录可能是从父进程继承而来的,可以自己另立山头。 关闭不需要的文件描述符。同样的,可能从父进程继承了一些打开的文件描述符,而这些描述符可能再也不需要,因此可以关闭。...重定向标准输出,标准输入和标准错误到/dev/null(相关阅读:Linux下你还知道这些特殊文件?) 实际上,从上面的描述可以发现,这些规则都有几乎相同的目标,那就是不想成为富二代,摆脱父亲的控制。...(在fork的介绍中,我们说到,儿子从父亲那里继承了很多东西) 重新设置权限掩码,避免受父进程影响 创建新的会话,脱离终端 使用新的工作目录 关闭不需要的文件描述符 关闭标准输入,标准输出和标准错误 所以通过这些也可以明白...0,1,2;实际上父进程可能没有打开2以上的文件描述符*/ int i; for(i = 3;i < rl.rlim_max;i++) close(i); return...为了保留printf的输出,我在daemonize函数中,并没有关闭所有的文件描述符,0,1,2可以参考《如何理解 Linux shell中“2>&1”?》

    2.6K20

    一个GO语言性能问题的发现和解决

    2 问题分析 ForkLock 的存在是为了避免下面的情况:在有多个goroutine同时fork exec的情况下, 为了子进程只继承它需要的文件描述符,需要在父进程在创建这些文件描述符的时候加上O_CLOEXEC...标志,这样在子进程中这些描述符是关闭的,子进程按需把自己需要继承的描述符打开即可。...Linux在2.6.27之后,打开文件或者管道,和设置O_CLOEXEC是一个原子操作,因此问题不大,但golang对内核版本的要求是2.6.23及以上,另外Unix系统中,open和设置O_CLOEXEC...是两个操作,如果在两个操作之间发生fork, 子进程就可能继承它不需要的文件描述符,因此需要加锁。...3 原因猜测 pipe2是一个快速系统调用,因此可能block的系统调用是clone和exec, 加上在go1.10上这个问题没有重现,对比go1.8代码和go1.9在forkAndExecInChild

    1.4K61

    【Linux内核】进程管理

    文章目录 简介 执行线程 两种虚拟机制 进程描述符与任务队列 PID 进程状态转化图 进程级联 进程创建过程 写时拷贝 fork() 线程在Linux中的实现 clone参数标志 内核线程 进程终结 删除进程描述符...链表中的每一项都是类型为task struct,称为进程描述符( process descriptor)的结构,该结构定义在/include/linux/sched.h文件中。...实际上,内核中大部分处理进程的代码都是直接通过task_struct进行的。 进程状态转化图 进程级联 Linux进程之间存在一个明显的继承关系。所有的进程都是PID为1的init进程的后代。...因为在一般情况下, 进程创建后都会马上运行一个可执行的文件。由于Unix强调进程快速执行的能力,所以这个优化是很重要的。 fork() Linux通过clone(系统调用实现fork()。...do_ fork完成了创建中的大部分工作,它的定义在kernel/fork.c文件中。该函数调用copy_process()函数,然后让进程开始运行。

    1.8K30

    你需要了解的 Linux 进程管理

    链表中的每一个元素为 task_struct 类型的结构体(定义在 linux/sched.h 中), task_struct 相对较大,在 32 位系统的机器上,大约有 1.7KB 的大小,该结构体中包含的数据能完整的描述一个正在执行的程序...Unix 系统的进程之间存在一个明显的继承关系,在 Linux 系统中也是如此,所有的进程都是 PID 为 1 的 init 进程的后代。而 init 进程是在系统启动的最后阶段启动的第一个进程。...Linux 的 fork() 使用写时拷贝(copy-on-wirte)页实现,这就意味着在创建子进程时可以推迟甚至免除拷贝父进程的数据。...因此 fork 的实际开销只有复制父进程的页表以及给子进程创建唯一的进程描述符。...着手使子进程与父进程区别开来,进程描述符内的不能继承的成员被清零或者初始化。 将进程状态设置为 TASK_UNINTERRUPTIBLE 避免被投入运行。

    60810

    守护进程(Daemon)

    fork 守护进程的父进程是 init 进程,在创建时先从父进程 fork 出来一个子进程,退出父进程,这时子进程变成孤儿,就成了 init 的子进程。...子进程会继承父进程的会话,进程组,控制终端,文件描述符等。 setid 通过setid()来创建新会话,同时也脱离了原来的进程组,会话以及控制终端,成为新的会话的组长。...此时它可能会再申请一个控制终端,所以我们再 fork 一下,并只保留新的子进程,这样就不是会话组长了,就不能申请控制终端了。 close(fd) 之后再关闭从父进程继承的文件描述符。...关闭之后我们要将文件描述符 0,1,2 重新定向到 "/dev/null",防止新打开的文件的文件描述符为 0,1,2。...exit(0); } // 关掉从父进程继承的文件描述符。

    7.7K30

    教你写一个守护进程

    在 Linux 中,系统与用户交互的界面称为终端,每一个从终端开始运行的进程都会依附于这个终端,这是上一小节给大家介绍的控制终端,也就是会话的控制终端。...在调用 fork 函数时,子进程继承了父进程的会话、进程组、控制终端等,虽然父进程退出了,但原先的会话期、进程组、控制终端等并没有改变,因此,那还不是真正意义上使两者独立开来。...子进程是继承了父进程的当前工作目录,由于在进程运行中,当前目录所在的文件系统是不能卸载的,这对以后使用会造成很多的麻烦。...由于使用 fork 函数新建的子进程继承了父进程的文件权限掩码,这就给子进程使用文件带来了诸多的麻烦。因此,把文件权限掩 码设置为 0,确保子进程有最大操作权限、这样可以大大增强该守护进程的灵活性。...,这使得守护进程不再持有从其父进程继承过来的任何文件描述符。

    1.6K30

    AirPlay Deamon学习(Linux Daemon)

    一个守护进程的父进程是init进程,因为它真正的父进程在fork出子进程后就先于子进程exit退出了,所以它是一个由init继承的孤儿进程。...; (3)在子进程中调用chdir函数,让根目录 ”/” 成为子进程的工作目录; (4)在子进程中调用umask函数,设置进程的umask为0; (5)在子进程中关闭任何不需要的文件描述符 说明:...方法是在第1点的基础上,调用setsid()使进程成为会话组长: setsid(); 说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。...可以通过使进程不再成为会话组长来禁止进程重新打开控制终端: if(pid=fork()) exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长) 关闭打开的文件描述符 进程从创建它的父进程那里继承了打开的文件描述符...对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如/tmpchdir(“/”) 重设文件创建掩模 进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。

    1.2K30

    Linux之守护进程理解(2)

    控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。 其方法是在fork()的基础上,调用setsid()使进程成为会话组长。...可以通过使进程不再成为会话组长来禁止进程重新打开控制终端,再fork()一次。 4、关闭打开的文件描述符 进程从创建它的父进程那里继承了打开的文件描述符。...8、记录信息 在Linux/Unix下有个syslogd的守护进程,向用户提供了syslog()系统调用。任何程序都可以通过syslog记录事件。 ...if (chdir("/tmp") == -1)     {         exit(1);     }     //关闭打开的文件描述符,或重定向标准输入、标准输出和标准错误输出的文件描述符。...进程从创建它的父进程那里继承了打开的文件描述符。如果不关闭,将会浪费系统资源,引起无法预料的错误。getdtablesize()返回某个进程所能打开的最大的文件数。

    2.6K30
    领券