多线程编程
学习《Linux高性能服务器编程》第十四章多线程编程,里面介绍了各种Linux编程中多线程编程的内容,为了印象深刻一些,多动手多实践,所以记下这个笔记。
这一章分为创建线程和结束线程、线程属性、Posix信号量、互斥锁、条件变量。
最近重温了神奇宝贝系列的动画,想到小时候在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
的子配置文件则指定各类日志的目标存储文件。