如何计算附加到特定共享内存段的进程数?

时间:2017-07-13 23:28:28

标签: c shared-memory

是否存在进程A(使用POSIX shm_open库创建共享内存段的方法 - 我对SysV共享内存API不感兴趣)以检测进程B是否已打开该进程共享内存段?我需要一种方法来启动流程A" work"在进程B打开相同的共享内存之后。该提议是针对A进行轮询,直到B​​连接为止。 (在我的例子中,实际上有3个进程B1,B2,B3所以我需要等到所有3个进程都打开共享内存)。

我一直在使用lsof /dev/shm/foo玩弄并抓取进程ID,但我不想仅仅为了执行此操作而调用shell。

我看到solve this problem by creating a semaphore的其他SO答案,我也可以使用其他一些邮件系统,但我一直在寻找一个移动部件较少的解决方案。

2 个答案:

答案 0 :(得分:0)

如果你希望一个接一个的工作开始,你应该依靠IPC信号。

例如:你的进程A向B发送一个他准备就绪的信号。 B处理信号并开始处理。

最终,您可以在shm_open()mmap()

中的/proc/{pid}/fd/文件描述符和/proc/{pid}/maps内存映射上看到一些流程活动

答案 1 :(得分:0)

我想出了这个。它避免以全局调用为代价进行系统调用,并取消引用每个/ proc / $ pid / fd / $ fd文件以查看它是否指向/ dev / shm / $ name共享内存设备。

#include <glob.h>

std::vector<int> GetPids(const std::string& name) const
{
      std::vector<int> result;
      const std::string shmmem = "/dev/shm/" + name;
      const std::string pat("/proc/*/fd/*");

      using namespace std;
      glob_t glob_result;
      glob(pat.c_str(), GLOB_TILDE, NULL, &glob_result);
      vector<string> ret;
      for (unsigned int i = 0; i < glob_result.gl_pathc; ++i)
      {
          char* fd = glob_result.gl_pathv[i];

// std::cout << "checking " << fd << std::endl;

          char fdlink[32];
          ssize_t len = readlink(fd, fdlink, sizeof(fdlink) -1);
          fdlink[len] = 0; // force a null termination
          if (len != -1)
          {
              std::cout <<  fd << " " << fdlink << std::endl;
              if (shmmem == fdlink)
              {
                  int pid = atoi(fd + 6);
                  if (pid != 0 && pid != getpid()) result.push_back(pid);
              }
          }
          else
          {
              perror("readlink failed");
          }
      }
      globfree(&glob_result);
      return result;
} 

这借用了busybox 'lsof' implementation的算法,但不使用busybox特定的库调用。