Linux进程间通讯(五)信号量

Linux进程间通讯

Linux进程间通讯(一)信号(上)

Linux进程间通讯(二)信号(下)

Linux进程间通讯(三)管道

Linux进程间通讯(四)共享内存

Linux进程间通讯(五)信号量

Linux进程间通讯(五)信号量

一、信号量集的创建

信号量集的创建需要通过系统调用 semget,其定义如下(这里需要注意的是,semget创建的是一个信号量集合,也就是一个集合是可以包含多个信号量的)

SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg)
{
   
	struct ipc_namespace *ns;
	static const struct ipc_ops sem_ops = {
   
		.getnew = newary,
		.associate = sem_security,
		.more_checks = sem_more_checks,
	};
	struct ipc_params sem_params;
	ns = current->nsproxy->ipc_ns;
	sem_params.key = key;
	sem_params.flg = semflg;
	sem_params.u.nsems = nsems;
	return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
}

  • key:表示信号量的id
  • msems:表示这个信号量集合中的信号量个数

这部分的操作和上一篇文章分析共享内存时创建共享内存十分相似。首先将请求封装成 sem_params,然后调用通用的 ipcget,指定信号量对应的 ipc 为 sem_ids,指定信号量对应的操作为 sem_ops,这一次请求的操作为 sem_params

ipcget 在上一篇文章已经解析过了,如果设置了 IPC_PRIVATE,那么就永远创建新的信号量;否则就会调用 ipcget_public

在 ipcget_public 中,首先会通过 id 去 sem_ids 中查找信号量是否存在,如果存在就返回,如果不存在,那么就创建一个新的

当要创建新的信号量的时候,对应的函数就是 newary 函数,其定义如下

static int newary(struct ipc_namespace *ns, struct ipc_params *params)
{
   
	int retval;
	struct sem_array *sma;
	key_t key = params->key;
	int nsems = params->u.nsems;
	int semflg = params->flg;
	int i;
......
	sma = sem_alloc(nsems);
......
	sma->sem_perm.mode = (semflg & S_IRWXUGO);
	sma->sem_perm.key = key;
	sma->sem_perm.security = NULL;
......
	for (i = 0; i < nsems; i++) {
   
		INIT_LIST_HEAD(&sma->sems[i].pending_alter);
		INIT_LIST_HEAD(&sma->sems[i].pending_const);
		spin_lock_init(&sma->sems[i].lock);
	}
	sma->complex_count = 0;
	sma->use_global_lock = USE_GLOBAL_LOCK_HYSTERESIS;
	INIT_LIST_HEAD(&sma->pending_alter);
	INIT_LIST_HEAD(&sma->pending_const);
	INIT_LIST_HEAD(&sma->list_id);
	sma->sem_nsems = nsems;
	sma->sem_ctime = get_seconds();
	retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
......
	ns->used_sems += nsems;
......
	return sma->sem_perm.id;
}

newary 的第一步就是分配一个 struct sem_array 对象,它表示一个信号量集对象,然后是设置信号量的属性,如 key、权限等

struct sem_array 中其实定义了多个信号量,具体多少个是通过 semget 系统调用指定的,其定义如下

struct sem_array {
   
	struct kern_ipc_perm	____cacheline_aligned_in_smp
				sem_perm;	/* permissions .. see ipc.h */
	time_t			sem_otime;	/* last semop time */
	time_t			sem_ctime;	/* last change time */
	struct sem		*sem_base;	
以下是在CentOS 7上搭建NTP时间服务器的步骤: 1.安装NTP软件包 ```shell yum install ntp -y ``` 2.配置NTP服务器 编辑`/etc/ntp.conf`文件,添加如下内容: ```shell # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). server 0.centos.pool.ntp.org iburst server 1.centos.pool.ntp.org iburst server 2.centos.pool.ntp.org iburst server 3.centos.pool.ntp.org iburst # Allow LAN traffic. restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap ``` 其中,`server`行指定了NTP服务器使用的公共时间服务器,`restrict`行指定了允许访问NTP服务器的IP地址范围。 3.启动NTP服务 ```shell systemctl start ntpd ``` 4.设置NTP服务开机自启动 ```shell systemctl enable ntpd ``` 5.检查NTP服务状态 ```shell systemctl status ntpd ``` 如果NTP服务正在运行,则输出类似以下内容: ```shell ● ntpd.service - Network Time Service Loaded: loaded (/usr/lib/systemd/system/ntpd.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2021-08-10 14:20:20 CST; 1h 5min ago Main PID: 1234 (ntpd) CGroup: /system.slice/ntpd.service └─1234 /usr/sbin/ntpd -u ntp:ntp -g ``` 6.检查NTP服务器是否正常工作 ```shell ntpq -p ``` 如果NTP服务器正常工作,则输出类似以下内容: ```shell remote refid st t when poll reach delay offset jitter ============================================================================== *0.centos.pool. .POOL. 16 p - 64 0 0.000 0.000 0.000 +1.centos.pool. .POOL. 16 p - 64 0 0.000 0.000 0.000 +2.centos.pool. .POOL. 16 p - 64 0 0.000 0.000 0.000 +3.centos.pool. .POOL. 16 p - 64 0 0.000 0.000 0.000 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值