0
我遇到了使用shmget()來管理內存段的問題。根據手冊頁,如果同時設置了IPC_CREAT和IPC_EXCL標誌,則shmget會在請求爲已存在的密鑰創建段時失敗。shmget與IPC_EXCL
我看到的是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;
}
}
我注意到了調零鍵,但它現在更有意義!謝謝 – chataign 2012-07-12 08:35:00