I write a shm struct as following:
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);
}
}
}
}
as you can see, the deconstructor will detach this shared memory and delete it.
but sometimes i need to ctrl-c to end the process. in that case, the shared memory will not be deleted.
is there any method can delete it safely if no live process linked the shared memory?
or delete it in the next time link?
Ctrl-C and similar keystrokes in some environments are processed by terminal and terminal invokes appropriate actions upon them, e.g. by calling
kill. In other cases it's handled by run-time library. You have to handle interrupts.E.g. in POSIX-compatible (which also includes console MinGW applications on Windows) Ctrl-C can be intercepted as SIGINT signal:
interruptHandlershould do something to cause process end gracefully. Which may include closing files, sockets, freeing other OS-related resources which aren't under normal circumstances by OS specs, callingatexit-handlers. Not all signals can be caught, when OS actually kills the process, it doesn't have that grace time.interruptHandleris called from what is known as signal trampoline, so provoking exceptions there is not recommended. See manpages.What can be used in handler is limited. In POSIX environment it's not safe to call
exit()from signal handler according to the list of safe functions. But_exit()or_Exit()wouldn't call anyatexitfunctions, it would do only init-related cleanup.