Vorrei implementare la comunicazione tra processi tra un client di registrazione C # 1 di Ubuntu Linux 15.10 mono 4.1.2 e un server video C # di Ubuntu Linux 15.10 mono 4.1.2 utilizzando una classe di Cex e classe di evento C ++ che utilizza pthreads, shm_open e mmap.
Il client del registratore e il server video risiedono sulla stessa macchina Ubuntu Linux. Inoltre, un client Windows 7 C # in esecuzione su una macchina separata comunica con un programma client-server Ubuntu Linux 15.10 C # utilizzando socket TCP / IP.
In Programmazione avanzata nella seconda edizione dell'ambiente UNIX di W. Richard Stevens e Stephen A. Rago, ho letto la pagina 489 che afferma
A memory-mapped region is inherited by a child across a fork (since it's part of the parent's address space) , but for the same reason, is not inherited by the new program across an exec
Ho bisogno di sapere se devo biforcare il programma del video server come un processo secondario "C" in modo che la comunicazione tra processi avvenga tramite il cast del valore di ritorno di mmap su un puntatore pthread_mutex_t. Voglio condividere la variabile pthread mutex e pthread condition tra il processo del server video e il processo client del registratore.
Ho confuso le discussioni con i processi?
Boost ha scritto un interessante articolo su questo argomento che ho estratto un estratto da mostrato di seguito,
Limitazioni durante la costruzione di oggetti in regioni mappate Puntatori offset invece di puntatori non elaborati
Quando due processi creano una regione mappata dello stesso oggetto mappabile, due processi possono comunicare scrivendo e leggendo quella memoria. Un processo potrebbe costruire un oggetto C ++ in quella memoria in modo che il secondo processo possa utilizzarlo. Tuttavia, una regione mappata condivisa da più processi, non può contenere alcun oggetto C ++, perché non tutte le classi sono pronte per essere un oggetto condiviso dal processo, specialmente se la regione mappata è mappata in indirizzi diversi in ogni processo.
Quando si posizionano oggetti in una regione mappata e si esegue il mapping di quella regione in indirizzi diversi in ogni processo, i puntatori grezzi rappresentano un problema poiché sono validi solo per il processo che li ha posizionati lì. Per risolvere questo problema, Boost.Interprocess offre uno speciale puntatore intelligente che può essere utilizzato al posto di un puntatore non elaborato. Pertanto, le classi utente contenenti puntatori non elaborati (o puntatori intelligenti Boost, che possiedono internamente un puntatore raw) non possono essere collocate in modo sicuro in una regione mappata condivisa dal processo. Questi puntatori devono essere sostituiti con puntatori offset e questi puntatori devono puntare solo agli oggetti posizionati nella stessa regione mappata se si desidera utilizzare questi oggetti condivisi da processi diversi.
Ovviamente, un puntatore posizionato in una regione mappata condivisa tra processi dovrebbe puntare solo a un oggetto di quella regione mappata. In caso contrario, il puntatore farebbe riferimento a un indirizzo in cui è valido un solo processo e altri processi potrebbero bloccarsi durante l'accesso a tale indirizzo.
Basile Starynkevitch ha scritto il 21 aprile 2016, "Il punto non è usare il mutex pthread e le variabili di condizione come il tuo sogno. Sii creativo anche ...", in risposta alla mia domanda su come emulare un evento di Windows in Linux.
Così, ho trovato il pdf, Implementare le variabili di condizione con semafori, link , scritto dal ricercatore di Microsoft, Andrew D Birrell. Sotto . Ho mostrato un estratto di questo articolo,
class Lock {
Semaphore sm;
public Lock() { // constructor
sm = new Semaphore(); sm.count =1; sm.limit = 1;
}
public void Acquire() { sm.P(); }
public void Release() { sm.V(); }
}
You can come quite close to implementing a condition variable in a similar way:
class CV {
Semaphore s;
Lock m;
public CV(Lock m) { // Constructor
this.m = m;
s = new Semaphore(); s.count = 0; s.limit = 1;
}
public void Wait() { // Pre-condition: this thread holds “m”
m.Release();
s.P();
m.Acquire();
}
public void Signal() {
s.V();
}
}
Potrei sfruttare la ricerca di Andrew D. Birrell per emulare un evento di Windows con una classe come questa:
class Event {
Lock theLock;
CV theCV;
bool triggered;
Event* MakeEvent(string Name);
Event* OpenEvent(string Name);
void CloseEvent(string Name, Event* anEvent);
void NukeEvent(string Name, Event* anEvent);
void SetEvent(Event* anEvent);
void ResetEvent(Event* anEvent);
int WaitForSingleObject(Event* anEvent, int millisecond);
}