2017-07-13 5 views
1

Gibt es eine Möglichkeit für Prozess A (die ein gemeinsames Speichersegment mit der Bibliothek POSIX shm_open erstellt - ich bin nicht an der Shared Memory-API SysV interessiert) zu erkennen, dass Prozess B das gleiche Shared-Memory-Segment geöffnet hat? Ich brauche einen Weg für Prozess A, um "Arbeit" zu starten, nachdem Prozess B denselben gemeinsamen Speicher geöffnet hat. Der Vorschlag ist, dass A etwas abfragt, bis B verbunden ist. (In meinem Fall gibt es tatsächlich 3 Prozesse B1, B2, B3, also muss ich warten, bis alle 3 den gemeinsamen Speicher geöffnet haben).Wie zähle ich die Anzahl der Prozesse, die an ein bestimmtes Shared-Memory-Segment gebunden sind?

Ich spielte mit lsof /dev/shm/foo und kratze die Prozess-IDs, aber ich möchte nicht nur eine Shell aufrufen müssen, um dies zu tun.

Ich sehe andere SO Antworten, die solve this problem by creating a semaphore und ich könnte auch ein anderes Messaging-System verwenden, aber ich war auf der Suche nach einer Lösung mit weniger beweglichen Teilen.

+2

'struct shmid_ds * buf' hat eine Variable namens' shm_nattch', die Sie abfragen können. Sie müssen 'shmctl' aufrufen, um diesen Puffer zu erhalten. –

+0

@COLDSPEED - Danke, aber ich muss die POSIX (aka "Realtime") 'shm_open' API verwenden, nicht die System V' shmctl' API. –

+0

@MarkLakata Ich denke, es wird funktionieren, weil es Teil der 'POSIX: XSI Extension' ist und auf der man-Seite es eindeutig angeben, dass es eine POSIX-Konformität ist. –

Antwort

0

Wenn Sie einen Arbeitsbeginn nach dem anderen haben möchten, sollten Sie sich auf IPC mit Signalen verlassen.

ZB: Ihr Prozess A sendet ein Signal an B, dass er bereit ist. B handhabt das Signal und beginnt mit der Verarbeitung.

Schließlich können Sie einige Prozessaktivitäten auf shm_open() Filedeskriptoren sehen und mmap() Speicherzuordnungen innerhalb /proc/{pid}/fd/ und /proc/{pid}/maps

0

ich mit diesem kam. Es wird vermieden, einen Systemaufruf auf Kosten eines Glob-Aufrufs durchzuführen und jede/proc/$ pid/fd/$ fd -Deferenz zu demeferenzieren, um zu sehen, ob sie auf das gemeinsam genutzte Speichergerät/dev/shm/$ name zeigt.

#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; 
} 

Dieser leiht den Algorithmus aus dem busybox 'lsof' implementation, mit Ausnahme nicht die Busybox spezifische Bibliothek Anrufe verwenden ist.

Verwandte Themen