我写了一个 shm 结构如下:
class ShmWorker {
public:
ShmWorker() = default;
virtual ~ShmWorker() {
shmdt(m_data);
shmctl(shmid, IPC_RMID, 0); // here is the problem, if ctrl-c, the shared memory
// won't be deleted
}
protected:
key_t get_keyid(const std::string & name) {
const std::string & s = "./" + name;
if (access(s.c_str(), F_OK) == -1) { const std::string & s1 = "touch " + s; system(s1.c_str()); }
key_t semkey = ftok(name.c_str(), 1);
CE(semkey == -1, "shm_file:%s not existed\n", s.c_str());
return semkey;
}
template <typename T>
void init(const std::string& name, int size) {
key_t m_key = get_keyid(name);
shmid = shmget(m_key, 0, 0); // TODO: check m_key existed
char * p;
if (shmid == -1) {
CE(errno != ENOENT && errno != EINVAL, "errno is %s\n", strerror(errno));
if (std::is_same_v<T, std::string>) shmid = shmget(m_key, sizeof(Header) + STRING_SIZE * size, 0666 | IPC_CREAT | O_EXCL);
else shmid = shmget(m_key, sizeof(Header) + sizeof(T) * size, 0666 | IPC_CREAT | O_EXCL);
CE(shmid == -1, "both connet and create are failed for shm\n")
printf("creating new shm %s %p\n", name.c_str(), p);
p = (char*)shmat(shmid, NULL, 0);
Header h(size, 0);
memcpy(p, &h, sizeof(Header));
} else {
p = (char*)shmat(shmid, 0, 0);
printf("existed m_data = %p\n", p);
}
}
}
}
如您所见,解构器将分离并删除此共享内存。
但有时我需要 ctrl-c 来结束进程。在这种情况下,共享内存不会被删除。
如果没有实时进程链接到共享内存,是否有任何方法可以安全地删除它?
或在下次链接中删除它?
Ctrl-C 和 some 环境中的类似击键由终端处理,终端对它们调用适当的操作,例如通过调用
kill
。在其他情况下,它由运行时库处理。你必须处理中断。
例如在 POSIX 兼容(也包括 Windows 上的控制台 MinGW 应用程序)中,Ctrl-C 可以作为 SIGINT 信号被拦截:
#include <iostream>
#include <thread>
#include <atomic>
#include <signal.h>
std::atomic<int> keepRunning;
void interruptHandler(int signum) {
keepRunning = 0;
}
void threadFunction() {
std::cout << "Hello, world!" << std::endl;
std::cout << "Press Ctrl-C to exit." << std::endl;
while(keepRunning);
std::cout << "Interrupt detected." << std::endl;
}
std::thread *infiniteThread;
void exitHandler() {
std::cout << "Bye, cruel world." << std::endl;
delete infiniteThread;
}
int main()
{
signal(SIGINT, interruptHandler);
std::atexit(exitHandler);
keepRunning = 1;
infiniteThread = new std::thread(threadFunction);
infiniteThread->join();
}