说起会话,我们经常登录到linux系统,执行各种各样的程序,这都牵涉到会话。但是,一般情况下我们又很少会去关注到会话的存在,很少会去了解它的来龙去脉。
  
  维系一个会话,最常见的有两种方式:
  一是基于某种凭证,比如web网站的登录会话,在登录验证之后,服务器就会返回一个session id作为凭证。用户之后的请求总是会带上这个id,而服务器通过这个id也就能知道用户是谁。直到用户注销登录、或者登录超时,服务器会清洗掉对应的session id,这个id就失效了,会话也就随之而结束。
  第二种方式是基于连接的,当用户和系统之间的连接启用时,系统会对用户进行验证,验证通过之后,来自这个连接的操作都是属于这个用户的。直到连接断开,则会话结束。
  
  linux系统的会话就是以第二种方式来维系的。会话基于连接,那么连接的安全性就决定了会话的安全性。以最常见的两种连接为例:
  1、本地连接,用户是直接通过键盘显示器来跟系统交互的,键盘显示器直接连接在主机上,连接被篡改基本上是不可能的;
  2、远程连接,以ssh为例,其协议会进行加密,从而避免连接被篡改;
  
  
  
  
调用以下函数可以使进程成为会话组长:

pid_t setsid(void)

要注意的是:
1.调用进程不能是进程组组长,该进程变成新会话首进程(session header)
2.该进程成为一个新进程组的组长进程。
3.需有root权限(ubuntu不需要)
4.新会话丢弃原有的控制终端,该会话没有控制终端
5.该调用进程是组长进程,则出错返回
6.建立新会话时,先调用fork, 父进程终止,子进程调用

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

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


输出结果:
child process PID is 3978
Group ID of child is 3977
Session ID of child is 3305
Changed:
child process PID is 3978
Group ID of child is 3978
Session ID of child is 3978

  
  
通过以下函数查看会话进程ID

pid_t getsid(pid_t pid)

pid为0表示察看当前进程session ID

注:组长进程不能成为新会话首进程,新会话首进程必定会成为组长进程。

Logo

更多推荐