I processi di lavoro dovrebbero accettare () o dovrebbero ricevere dati dal processo principale?

0

Sto provando a scrivere un application server in python. Ho un processo master e più processi di lavoro creati dal master utilizzando fork (). Ho in mente due approcci su come i lavoratori dovrebbero gestire i dati delle richieste.

  1. L'uso delle pipe passa i dati ricevuti dal master usando accept () a un lavoratore inattivo. Il lavoratore riceve i dati, li elabora e invia i dati attraverso un'altra pipe al master che li rimanda al client.
  2. Poiché i lavoratori ereditano il descrittore del file socket di ascolto dal master, rendono accettabile ogni chiamata worker (). In questo caso, presumo che il kernel deciderà a quale operatore i dati dovrebbero essere dati.

Quali sono i pro e i contro per i due precedenti approcci?

    
posta akshay takkar 28.10.2018 - 11:34
fonte

1 risposta

0

Se tutti i dati vengono inviati attraverso il processo del coordinatore, il processo di coordinamento diventa un collo di bottiglia e un livello di buffering completamente inutile. Quindi la tua prima soluzione dovrebbe essere evitata.

Ci sono un paio di alternative per distribuire il carico su più processi di lavoro:

  • Avere un ciclo accept() nel processo coordinatore, quindi fork() di un processo di lavoro all'interno di quel ciclo per gestire il socket accettato. Questo è il classico design del demone ed è facile da implementare in C o Perl. Ma può essere difficile da implementare correttamente con Python perché la biforcazione ha interazioni sorprendenti con il multithreading e il tuo programma Python potrebbe eseguire più thread di quanto ti aspetteresti.

  • Avere un ciclo accept() nel processo coordinatore, quindi inviare il descrittore di file del socket accettato al processo di lavoro su un socket AF_UNIX con un messaggio SCM_RIGHTS. Questo è simile a dup() in fd attraverso un limite di processo. Questa può essere una soluzione elegante che consente al processo del coordinatore di decidere quale processo di lavoro gestirà la connessione.

  • Tutti i processi di lavoro eseguono il proprio ciclo accept() , ma consentono loro di ascoltare su una porta condivisa utilizzando il flag SO_REUSEPORT. Il kernel decide quindi quale processo di lavoro riceve una connessione in entrata. Questo è più appropriato per uno scenario di bilanciamento del carico perché il processo del coordinatore non interferisce con la connessione, ma questo non funziona con tutti i tipi di socket.

    Questo è simile alla seconda soluzione in cui si inizia ad ascoltare su una porta e poi si biforcano i processi di lavoro, tranne che non è necessario iniziare ad ascoltare prima di biforcarsi e che entrambe funzioneranno solo con SO_REUSEPORT.

risposta data 28.10.2018 - 13:36
fonte

Leggi altre domande sui tag