ctrl c时如何删除共享内存?

问题描述 投票:0回答:1

我写了一个 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 来结束进程。在这种情况下,共享内存不会被删除。

如果没有实时进程链接到共享内存,是否有任何方法可以安全地删除它?

或在下次链接中删除它?

c++ ipc shared-memory
1个回答
0
投票

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.