Devo dividere il programma C ++ in più applicazioni interattive?

2

Stiamo discutendo la proposta di suddividere un grande programma C ++ in più eseguibili separati che comunicherebbero usando la memoria condivisa. Le strutture dati condivise sono grandi, quindi non vogliamo usare la rete loopback o qualsiasi altro approccio che le copierebbe.

Gli argomenti per la suddivisione sono che ogni parte può essere sviluppata separatamente, potenzialmente sostituendola con l'implementazione alternativa, anche in un'altra lingua. Eviterebbe naturalmente l'accesso a dati e codice privati e i processi verrebbero ovviamente eseguiti in thread separati.

Gli argomenti contro sarebbero che C ++ ha built-in mezzi per strutturare anche un progetto ampio e complesso, nascondendo i dati e le funzioni come progettato. È possibile utilizzare il multithreading C ++ per utilizzare tutti i core della CPU. In questo caso i dati possono essere passati per riferimento da un modulo all'altro senza trucchi.

Esiste una visione ampiamente accettata sulla divisione di un programma C ++ in più binari eseguiti in parallelo sullo stesso host? I programmi più conosciuti funzionano in questo modo?

I suggerimenti da implementare in un'altra lingua non rientrano nell'ambito di questa domanda.

    
posta h22 18.01.2018 - 12:42
fonte

3 risposte

6

multiple separate executables that would communicated using shared memory

Questa è una pessima idea, perché improvvisamente il tuo programma è impossibile da eseguire il debug. Se il processo A si blocca mentre si guardano alcuni dati nell'area condivisa, è possibile metterlo in pausa nel debugger, ma il processo B è libero di continuare e sovrascrivere i dati sospetti. La concorrenza della memoria condivisa è generalmente considerata problematica anche quando gli accessor fanno parte dello stesso programma multi-thread.

Penso che l'unico grande esempio che posso pensare che usi la memoria condivisa sia X windows.

I problemi di coerenza della cache significano che la memoria condivisa può avere una semantica sorprendente; normalmente ci si aspetterebbe di scrivere per indirizzare A, quindi l'indirizzo B implicherebbe che un altro processo che vede il valore aggiornato dell'indirizzo B vedrebbe anche l'indirizzo A un cambiamento, ma potrebbe non essere sempre vero.

Ma sembra che l'applicazione non sia ancora multithread. Suggerirei di iniziare con questo in quanto è notevolmente più facile lavorare e le primitive sono migliori.

every part can be developed separately, potentially replacing it with the alternative implementation, even in another language

Devi essere molto rigoroso sulla definizione del layout della memoria condivisa se hai intenzione di farlo. Diventa molto più simile a un database in-memory o al formato file. Ad esempio, non è possibile avere oggetti nella memoria condivisa con funzioni virtuali attive, devono essere tutti tipi POD.

    
risposta data 18.01.2018 - 14:38
fonte
3

The arguments for splitting are that every part can be developed separately,

Non hai bisogno di eseguibili separati per farlo. Non hai nemmeno bisogno di binari separati (dll o così) per quello. Hai solo bisogno di interfacce ben definite.

potentially replacing it with the alternative implementation,

Di nuovo, questo non richiede un file eseguibile separato.

even in another language.

Hai un caso aziendale legittimo che richiede questo? In caso contrario, non considerarlo nemmeno.

    
risposta data 18.01.2018 - 14:51
fonte
2

tl; dr - non sembra che i possibili benefici di più processi siano le cose che ti interessano, e le cose che fai menzionano per quanto riguarda il lavoro almeno altrettanto bene con più thread.

A seconda della piattaforma, non esiste necessariamente un'enorme distinzione tra memoria condivisa a più processi e thread multipli a singolo processo.

In entrambi i casi si hanno più thread schedulable di esecuzione che condividono alcune risorse e approssimativamente gli stessi requisiti per la sincronizzazione dell'accesso ad essi.

Le principali differenze sono:

  1. più processi sono potenzialmente più difficili da debug come dice pjc50 (non puoi semplicemente fermare tutto in un debugger, o ottenere un singolo file core)
  2. più processi sono potenzialmente più facili da test , dato che hai un limite naturale per prendere in giro altri componenti

    Ovviamente può testare componenti ben definiti in-process, ma questo sarà un processo di test unitario piuttosto che un processo di produzione indipendente. Questa distinzione probabilmente non ha importanza nella maggior parte delle situazioni.

  3. non è possibile utilizzare i puntatori grezzi nella memoria condivisa tra i processi, poiché è mappato in uno spazio indirizzo diverso. Tuttavia, puoi utilizzare offset o altri tipi di handle o indici e, se non utilizzi i puntatori, non fa alcuna differenza
  4. puoi davvero condividere solo POD o tipi banali-inizializzabili nella memoria condivisa - i puntatori vtable hanno lo stesso problema degli altri (RTTI e gli indirizzi di funzione sono anche specifici del processo)

Ora, i vantaggi che in genere le persone cercano in più processi sono:

  1. resilienza: un errore fatale in un processo non elimina tutto
  2. sicurezza: esecuzione di plug-in o script non attendibili senza consentire l'accesso all'intero spazio indirizzo o all'utente meno privilegiato
  3. asincronicità - questa è davvero una preoccupazione solo se vuoi che qualcosa funzioni in parallelo, ma il resto del tuo programma non può essere modificato per adattarsi a questo
  4. partizionamento delle risorse: alcuni programmi (ad esempio i server Web) possono utilizzare tutti i descrittori di file consentiti per un singolo processo e devono eseguire più istanze.

    I programmi a 32 bit potrebbero avere un problema simile con lo spazio degli indirizzi, ma non è probabile che costituisca una limitazione se si costruisce a 64 bit. potresti volere un processo per socket su un sistema NUMA, ma poi non non condividerai mai la memoria tra loro, quindi non corrisponde comunque al tuo caso.

Si noti che nessuno dei potenziali vantaggi dell'utilizzo di più processi richiede la condivisione della memoria. La resilienza e la sicurezza in particolare funzionano meglio con la comunicazione serializzata.

    
risposta data 18.01.2018 - 15:00
fonte

Leggi altre domande sui tag