setsid的作用

百度了一圈setsid的作用,基本都是一个抄袭一个,真的是太桑心,引用百度百科原话:

当进程是会话的领头进程时setsid()调用失败并返回(-1)。
setsid()调用成功后,返回新的会话的ID,调用setsid函数的进程成为新的会话的领头进程,并与其父进程的会话组和进程组脱离。
由于会话对控制终端的独占性,进程同时与控制终端脱离。


这段解释比较费解,用代码说明:

[cpp]  view plain  copy
  1. #include <sys/file.h>  
  2. #include <stdio.h>  
  3. #include <unistd.h>  
  4. #include <stdlib.h>  
  5. #include <sys/file.h>  
  6.                                           
  7. int main (int argc, char ** argv)  
  8. {  
  9.      if ( fork() > 0 ) {  
  10.           printf ( "parent begin\n" ) ;  
  11.           sleep(10);  
  12.             
  13.         printf ( "parent exit\n" ) ;  
  14.         exit ( 0 ) ;  
  15.      }  
  16.        
  17.      printf ( "child begin\n" ) ;  
  18.      sleep(100);  
  19.        
  20.      printf ( "child exit\n" ) ;  
  21.      return 0 ;  
  22. }  


上面这段代码,运行时父进程等待10s,子进程等待100s

应用启动:



打开另外一个终端窗口,查看进程存在,testSetSid同在一个进程组:



关闭运行testSetSid的终端运行窗口,再查看进程,进程组退出,父子进程都已不在:





说明:父子进程都受终端影响,终端退出,父子进程也会退出




如果我们在子进程开始时调用setsid():

[cpp]  view plain  copy
  1. #include <sys/file.h>  
  2. #include <stdio.h>  
  3. #include <unistd.h>  
  4. #include <stdlib.h>  
  5. #include <sys/file.h>  
  6.                                           
  7. int main (int argc, char ** argv)  
  8. {  
  9.      if ( fork() > 0 ) {  
  10.           printf ( "parent begin\n" ) ;  
  11.           sleep(10);  
  12.             
  13.         printf ( "parent exit\n" ) ;  
  14.         exit ( 0 ) ;  
  15.      }  
  16.        
  17.      <span style="color:#ff0000;">setsid();</span>  
  18.      printf ( "child begin\n" ) ;  
  19.      sleep(100);  
  20.        
  21.      printf ( "child exit\n" ) ;  
  22.      return 0 ;  
  23. }  


重新启动应用:




查看进程,testSetSid分为两个进程组:




关闭运行testSetSid的终端窗口,查看进程,父进程退出,子进程继续存在:



说明:setsid后子进程不受终端影响,终端退出,不影响子进程




程序中umask(0)什么意思?

linux中的 umask 函数主要用于:在创建新文件或目录时 屏蔽掉新文件或目录不应有的访问允许权限。文件的访问允许权限共有9种,分别是:r w x r w x r w x(它们分别代表:用户读 用户写 用户执行 组读 组写 组执行 其它读 其它写 其它执行)。

其实这个函数的作用,就是设置允许当前进程创建文件或者目录最大可操作的权限,比如这里设置为0,它的意思就是0取反再创建文件时权限相与,也就是:(~0) & mode 等于八进制的值0777 & mode了,这样就是给后面的代码调用函数mkdir给出最大的权限,避免了创建目录或文件的权限不确定性。

open("/dev/null",o_rdwr)作用

 open("/dev/null",..)

很多程序在一开始的时候要做这样的处理
/* 
* make sure we have stdin/stdout/stderr reserved
*/

while((t = open("/dev/null",O_RDWR)) < 3 && T >= 0)
if(t >= 3) close(t)

写入/dev/null的东西会被系统丢掉
就像注释写的那样,对stdin/stdout/stderr进行保护
代码中利用while先把文件描述符0,1,2分配出去,以后再分配
的时候就不会将stdin/stdout/stderr打开,以达到保护目的。

linux下的stdin,stdout,stderr详解

stdout, stdin, stderr的中文名字分别是标准输出,标准输入和标准错误。

 

Linux下,当一个用户进程被创建的时候,系统会自动为该进程创建三个数据

流,也就是题目中所提到的这三个。那么什么是数据流呢(stream)?我们知道,一个程序要运行,需要有输入、输出,如果出错,还要能表现出自身的错误。这是就要从某个地方读入数据、将数据输出到某个地方,这就够成了数据流。

 

因此,一个进程初期所拥有的这么三个数据流,就分别是标准输出、标准输入和标准错误,分别用stdout, stdin, stderr来表示。对于这三个数据流来说,默认是表现在用户终端上的,比如我们在c中使用fprintf:

fprintf(stdout,"hello world!\n");

 

屏幕上将打印出"hello world!"来,同样,我们使用:

上面的代码会接收用户输入在终端里的字符,并存在ptr中。

fread(ptr,1,10,stdin);

 

那么标准输入输出和错误是不是只能反应在终端里呢?答案是不是的!我们可以

将标准输入和输出重定位到文件中:

例如,我们使用ls命令,会把当前目录下的文件名输出到终端上:

$ls

gcc  gcc.sh gmp-5.0.1 gmp-5.0.1.tar.bz2

linux-loongson-community-2.6.35-rc1 longene-0.3.0-linux-2.6.34

mpfr-3.0.0 mpfr-3.0.0.tar.gz oprofile-0.9.6

我们可以使用“ > ”符号,将ls的标准输出重定向到文件中:

$ls  >  lsout 将标准输出重定向为文件lsout

$more  lsout 显示lsout文件里的内容

gcc  gcc.sh gmp-5.0.1 gmp-5.0.1.tar.bz2

linux-loongson-community-2.6.35-rc1 longene-0.3.0-linux-2.6.34

mpfr-3.0.0 mpfr-3.0.0.tar.gz oprofile-0.9.6

同样,我们也可以使用“ < ”符号将标准输入重定向到文件中,以sort为例,以下示例使用 sort命令对由键盘键入的文本进行排序。键入ctrl-D 结束标准输入。终端屏幕显示的标准输出如下:

$sort

muffy

happy

bumpy

CTRL-D //结束标准输入。

 

bumpy

happy

muffy //结束标准输出。

 

使用" < "重定向后为:

$ more socks 显示 socks的内容。

polka dot

argyle

plaid 

 

$ sort < socks 将输入重定向为从 socks输入,并将内容排序。

argyle

plaid

polka dot

好,基本知识讲完了,我们知道,标准输出和标准错误默认都是将信息输出到终端上,那么他们有什么区别呢?让我们来看个题目:

 

问题:下面程序的输出是什么?(intell笔试2011

Int  main(){

fprintf(stdout,"Hello ");

fprintf(stderr,"World!");

return0;

}

解答:这段代码的输出是什么呢?你可以快速的将代码敲入你电脑上(当然,拷贝更快),然后发现输出是

World! Hello

这是为什么呢?在默认情况下,stdout是行缓冲的,他的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。而stderr是无缓冲的,会直接输出,举例来说就是printf(stdout, "xxxx")  printf(stdout, "xxxx\n"),前者会憋住,直到遇到新行才会一起输出。而printf(stderr, "xxxxx"),不管有么有\n,都输出。



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值