Linux定时器
学习《Linux高性能服务器编程》第十一章定时器,里面介绍了各种网络程序中的定时事件,为了印象深刻一些,多动手多实践,所以记下这个笔记。这一篇主要记录Linux中SIGALRM信号触发的定时器。
最近重温了神奇宝贝系列的动画,想到小时候在GBA上玩的口袋妖怪系列游戏,想在电脑上重新玩一下,所以记录一下几个开源的GBA游戏模拟器。
仓库地址:https://github.com/visualboyadvance-m/visualboyadvance-m
直接去release里面下载
visualboyadvance-m-Win-64bit.zip是打包好的模拟器。
translations.zip是翻译文件,因为原版是英文的,我们想用中文就得下载这个
Linux下每个进程都隶属于一个进程组,因此它们除了PID信息外,还有进程组ID(PGID
)。我们可以用如下函数来获取指定进程PGID
:
1 | #include <sys/types.h> |
该函数成功时返回进程pid所属进程组的PGID
,失败则返回-1并设置errno
。
每个进程组都有一个首领进程,其PGID
和PID
相同。进程组将一直存在,直到其中所有进程都退出,或者加入到其他进程组。下面的函数用于设置PGID
:
1 | int setpgid(pid_t pid, pid_t pgid); |
该函数将PID
为pid
的进程的PGID
设置为pgid
。
如果pid
和 pgid
相同,则由pid
指定的进程将被设置为进程组首领;
如果pid
为0,则表示设置当前进程的PGID
为pgid
;
如果pgid
为0,则使用pid
作为目标PGID
。
setpgid
函数成功时返回0,失败则返回-1并设置errno
.
一个进程只能设置自己或者其子进程的PGID
。并且,当子进程调用exec
系列函数后,我们也不能再在父进程中对它设置PGID
。
Linux中id真是太多了进程有pid,然后用户还有UID这种,真是有点绕。
在Linux当中一个进程(程序)拥有四个ID:真实用户UID
、有效用户EUID
、真实组GID
和有效组EGID
。
这里以真实用户UID
和有效用户EUID
为例,真实组GID
和有效组EGID
道理是相同的。
EUID
存在的目的是方便资源访问:它使得运行程序的用户拥有该程序的有效用户的权限(太过官方这种说法感觉)。EUID
确定进程对某些资源和文件的访问权限。在大多数情况下,进程的UID
和EUID
是一样的,但是对于一些程序如su
、passwd
这种set-user-id
程序,它们有可能是不相同的。对于set-user-id
程序而言,程序的EUID
会变成程序的所有者的UID
,也就是说程序执行时,是以程序的所有者身份进行运行的。
Linux上使用rsyslogd
守护进程接收用户进程输出的日志和接收内核日志。
用户进程是通过syslogd
函数生成系统日志。该函数将日志输出到一个UNIX本地域socket类型(AF_UNIX)的文件/dev/log
中,rsyslogd
则监听该文件以获取用户进程的输出。
内核日志是如何进行管理的,在这里我们不进行关系。
rsyslogd
守护进程在接收到用户进程或内核输入的日志后,会把它们输出至某些特定的日志文件。默认情况下,调试信息会保存至/var/log/debug
文件,普通信息保存至/var/log/messages
文件,内核消息则保存至/var/log/kern.log
文件。
不过,日志信息具体如何分发,可以在rsyslogd
的配置文件中设置。rsyslogd
的主配置文件是/etc/rsyslog.conf
,其中主要可以设置的项包括:内核日志输入路径,是否接收UDP日志及其监听端口(默认是514,见/etc/services
文件),是否接收TCP日志及其监听端口,日志文件的权限,包含哪些子配置文件(比如 /etc/rsyslog.d/*.conf
)。rsyslogd
的子配置文件则指定各类日志的目标存储文件。
tee
函数在两个管道描述符之间复制数据,也是零拷贝操作。它不消耗数据,因此源文件描述符上的数据仍然可以用于后续操作。
1 | #include <fcntl.h> |
fd_in
和fd_out
是文件描述符,但是必须是管道文件描述符
len
参数指定移动数据的长度
flags
参数则控制数据如何移动,它可以被设置为下表中的某些值的按位或,它的参数其实和splice
函数相同。
tee
函数成功时返回在两个文件描述符之间复制的数据数量(字节数)。返回0表示没有复制任何数据。tee
失败时返回-1并设置errno
。
splice
用于在两个文件描述符之间移动数据,是零拷贝操作。看了man
手册,发现这个splice
函数跟pipe管道关系不浅。
1 | #include <fcntl.h> |
fd_in
参数是待输人数据的文件描述符。如果fd_in
是一个管道文件描述符,那么 off_in
参数必须被设置为NULL。如果fd_in
不是一个管道文件描述符(比如 socket),那么off_in
表示从输入数据流的何处开始读取数据。此时,若off_in
被设置为NULL,则表示从输入数据流的当前偏移位置读入;若off_in
不为NULL,则它将指出具体的偏移位置。
fd_out/off_out
参数的含义与fd_in/off_in
相同,不过用于输出数据流。
len
参数指定移动数据的长度
flags
参数则控制数据如何移动,它可以被设置为下表中的某些值的按位或。