Mic*_*ael 8 c++ linux concurrency mutex semaphore
是否可以在Linux上用C++创建系统范围的全局变量/信号量/互斥量?
原因如下:我有一个系统经常在不相关的数据上运行同一软件的多个副本.通常有4个作业,每个作业运行相同的软件.该软件有一个小部分,它创建一个占用大量内存的巨大图形; 在该部分以外的内存使用量适中.
有时会发生这样的情况,即2个作业同时遇到同样占用大量内存的部分,整个系统开始交换.因此,我们希望通过在不同作业之间创建类似于临界区互斥体的东西来防止这种情况,这样一次就不会有多个内存分配大量内存.
如果这些是相同工作的线程,pthread锁将完成这项工作.
在不同的工作之间实现这种互斥量的好方法是什么?
对于进程间互斥,可以使用文件锁定。使用linux,代码就像通过调用来保护关键部分一样简单flock。
int fd_lock = open(LOCK_FILE, O_CREAT);
flock(fd_lock, LOCK_EX);
// do stuff
flock(fd_lock, LOCK_UN);
Run Code Online (Sandbox Code Playgroud)
如果需要POSIX兼容性,可以使用fcntl。
您可以使 C++ 互斥体在 Linux 上跨进程边界工作。然而,其中涉及一些黑魔法,这使得它不太适合生产代码。
标准库的std::mutex和在底层std::shared_mutex使用 pthread 的struct pthread_mutex_s和。pthread_rwlock_t该native_handle()方法返回指向这些结构之一的指针。
缺点是某些细节是从标准库中抽象出来并在实现中默认的。例如,通过将第二个参数传递给 来std::shared_mutex创建其底层pthread_rwlock_t结构。这应该是指向包含确定共享策略的属性的结构的指针。NULLpthread_rwlock_init()pthread_rwlockattr_t
public:
__shared_mutex_pthread()
{
int __ret = pthread_rwlock_init(&_M_rwlock, NULL);
...
Run Code Online (Sandbox Code Playgroud)
理论上,它应该接收默认属性。根据手册页pthread_rwlockattr_getpshared():
进程共享属性的默认值为 PTHREAD_PROCESS_PRIVATE。
也就是说,无论如何,两者std::shared_mutex 都 std::mutex可以跨进程工作。我正在使用 Clang 6.0.1(x86_64-unknown-linux-gnu / POSIX 线程模型)。以下是我要检查的内容的描述:
使用 来创建共享内存区域shm_open。
检查区域的大小以fstat确定所有权。如果.st_size为零,那么ftruncate()它和调用者都知道这是该区域的创建过程。
打电话mmap吧。
new构造一个std::mutex或对象。std::shared_mutexreinterpret_cast<>()获取指向同一对象的类型化指针。现在,这些进程会在调用时trylock()并unlock()每隔一定时间循环一次。printf()您可以使用before 、 aftertrylock()和 before看到它们互相阻塞unlock()。
额外的细节:我对 c++ 头文件或 pthreads 实现是否有错误感兴趣,所以我深入研究了pthread_rwlock_arch_t. 您将找到一个__shared为零的属性,以及一个__flags由 表示的字段也为零的属性__PTHREAD_RWLOCK_INT_FLAGS_SHARED。因此,默认情况下,该结构似乎并不打算共享,尽管它似乎无论如何都提供了此功能(截至 2019 年 7 月)。
它似乎有效,尽管有些偶然。我建议在编写与文档相反的生产软件时要小心。
| 归档时间: |
|
| 查看次数: |
7097 次 |
| 最近记录: |