繁体   English   中英

了解 sem_open()

[英]Understanding the sem_open()

我正在使用命名信号量,这是我的 sem_proc.cpp 进程代码:

# include <iostream>
# include <string.h>
# include <unistd.h>
# include <semaphore.h>
# include <fcntl.h>

using namespace std;

int main(){
  sem_t *sem;
  string sem_name = "/my_sem";
  int value = 1;

  sem = sem_open(sem_name.c_str(), O_CREAT, 0644, value);
  cout << "sem_addr : " << sem << endl;
  
  cout << "sem_wait_result: " << sem_wait(sem) << endl;
  cout << "Enterd into CS" << endl;
  sleep(5);   // sleep for 5 seconds
  cout << "Waked up and now going out of CS" << endl;
  sem_post(sem);
  
  sem_close(sem);
  return 0;
}

我编译了:

g++ sem_proc.cpp -lpthread

然后在两个不同的终端上运行代码:

./a.out

终端 1 的输出是:

sem_addr : 0x7fef162de000
sem_wait_result: 0
Enterd into CS
Waked up and now going out of CS

终端 2 的输出是:

sem_addr : 0x7f53836a2000
sem_wait_result: 0
Enterd into CS
Waked up and now going out of CS

两个终端中名称为“/my_sem”的命名信号量地址不应该与我在 sem_open 期间使用 O_CREAT 的地址相同,还是我遗漏了什么?

不要期望信号量在不同的进程中具有相同的内存地址。 这不是信号量本身, sem_t是程序与信号量接口所需的数据副本。 信号量本身由操作系统处理。

确切位置因很多因素而变得复杂:地址随机化、malloc、mmap 等。

C 标准库中的sem_t是一种保存有关信号量信息的结构,它通常是通过调用带有标志MAP_SHARED mmap来创建的,以告诉内核使用预先分配的共享内存区域。 信号量(在 Unix 系统中)实际上只是文件描述符,因此需要在线程之间共享将它们映射到内存中。

这个映射的内存地址由内核决定,基于其他映射文件和区域,这解释了为什么它每次都不同。 内核会随机分配地址布局,以防止缓冲区溢出造成的漏洞利用。

有关更多信息,请阅读mmap系统调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM