带有 IPC_EXCL 的 shmget
Posted
技术标签:
【中文标题】带有 IPC_EXCL 的 shmget【英文标题】:shmget with IPC_EXCL 【发布时间】:2012-07-11 12:37:01 【问题描述】:我在使用 shmget() 管理内存段时遇到问题。根据手册页,如果同时设置了 IPC_CREAT 和 IPC_EXCL 标志,如果要求为已存在的密钥创建段,则 shmget 应该会失败。
我看到的是 shmget 无论如何都会为同一个键(使用新的 shmid)创建一个新段。下面的代码说明了这个问题。我正在运行它的两个实例,一个处于“创建者”模式,一个处于“客户端”模式。
./test 10 0
./test 10 1
创建者为 key=10 分配一个内存段,然后附加到它。客户端还附加到该段。运行 ipcs -m 我可以看到该段存在并且附加了两个进程。
然后我让创建者销毁该段,正如预期的那样,ipcs 显示它已标记为销毁,仍然附加 1 个进程。奇怪的是,如果我用相同的键再次启动创建者,它会创建一个新的段而不是因为段已经存在而失败?
感谢您的帮助!
#include <sys/shm.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <stdexcept>
using namespace std;
int main( int argc, char** argv )
cout << "usage: " << argv[0] << " <key> <mode (0=creator 1=client)>" << endl;
if ( argc < 3 ) return 0;
int key = atoi( argv[1] );
int mode = atoi( argv[2] );
cout << "key=" << key << endl;
cout << "mode=" << mode << endl;
char c;
int shmid=-1;
int size = 100; // bytes
try
if ( mode == 0 ) // creator
cout << "creating segment" << endl;
int flags = ( IPC_CREAT | IPC_EXCL | 0666 );
shmid = shmget( key, size, flags );
if ( shmid== -1 )
throw runtime_error("failed to create segment");
cout << "created: shmid=" << shmid << endl;
else if ( mode == 1 )
shmid = shmget( key, 0, 0 );
if ( shmid== -1 )
throw runtime_error("failed to load");
cout << "loaded: shmid=" << shmid << endl;
cout << "attach? (press key to continue)" << endl;
cin >> c;
void* data = shmat( shmid, NULL, 0 );
if ( data == (void *) -1 )
throw runtime_error("failed to attach");
cout << "attached to id=" << shmid << endl;
cout << "destroy? (press key to continue)" << endl;
cin >> c;
if ( shmctl( shmid, IPC_RMID, NULL ) == -1 )
throw runtime_error("failed to destroy");
cout << "destroyed" << endl;
catch( const exception& e )
cout << e.what() << " errno=" << errno << endl;
【问题讨论】:
【参考方案1】:您应该密切关注ipcs
的输出。使用带有10
键的示例代码。
服务器已创建分段:
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0000000a 1470791680 hristo 666 100 1
客户端已连接,服务器已将段标记为销毁:
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 1470791680 hristo 666 100 1 dest
^^^^^^^^^^
由于预计没有新进程能够通过其密钥找到并附加此类段,因此密钥被归零。这就是为什么您可以使用相同的密钥创建一个新的。
【讨论】:
我注意到了归零的键,但现在更有意义了!谢谢以上是关于带有 IPC_EXCL 的 shmget的主要内容,如果未能解决你的问题,请参考以下文章
带有多个链接的 NSAttributedString 的 UILabel,带有行限制,显示尾部截断,带有未见文本的 NSBackgroundColorAttributeName