|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Mar 2006
Messaggi: 131
|
[C]problemi di visibilità variabili globali tra processi padri e figli..
ho una variabile
t_newclient ** clienti; che dichiaro fuori dal main come variabile globale,questa è un puntatore a tutti i puntatori a delle strutture di tipo t_newclient; queste dentro hanno un campo nome e un campo pid quando un cliente si connette,nel campo t_newclient.pid viene aggiornato il pid del cliente e quando se ne va il suo pid viene messo a 0. questo perchè nel caso arrivi al server un SIGINT questo nel gestore scorre la struttura dati e tutti i pid che non sono a 0 vengono avvertiti. PROBLEMA: il cliente se ne va e il pid viene azzerato....se dopo però lancio un interruzione al server questo nella struttura dati trova ancora il pid del cliente e la kill sul pid che non esiste più dà errore la struttura dati è globale,dichiarata fuori dal main,inizializzata appena dentro il main,a questa possono accedere anche i processi figli(ognuno tratta un cliente differente e si preoccupa di rimuovere il pid quando se ne va) non capisco perchè non debba rimanere aggiornata quando il gestore la va a scorrere..... |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Fammi capire...lanci i child con fork e pretendi che accedano alla memoria del padre?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Mar 2006
Messaggi: 131
|
il problema è che se arriva un SIGINT al server,questo prima di uscire completamente dal programma deve lanciare una SIGINT ai clienti ancora connessi..
il fatto è che se i clienti che si sono loggati lasciano il programma con una exit tramite i figli,il padre non saprà mai quale dei client connessi avvertire o meno,sto cercando una soluzione a questo dilemma qua...(idee?) credevo che una variabile globale potesse risolvere,ma hai ragione è una cazzata perchè sono pur sempre due processi distinti e ognuno ha il suo stack... grazie |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Non è che si capisce molto quello che hai tirato su dalla tua descrizione...se può aiutarti, sappi che un child che termina causa l'invio al padre di un SIGCHLD che puoi intercettare. Dentro l'handler del segnale puoi eseguire una waitpid che ti ritorna il pid del child terminato.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
Perche´ il client deve conoscere il proprio nome e i l proprio pid (il pid lo puo´ ottenere comunque con la getpid(), il nome glielo puoi passare come argomento) ? E poi, come ti ha fatto notare ilsensine, se la variabile non la passi al processo (execvp etc) ti puoi scordare la visibilita´ delle variabili globali (che sono comunque sconsigliate).
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#6 |
Member
Iscritto dal: Mar 2006
Messaggi: 131
|
la situazione è:
-cliente si logga -server affida al cliente un processo figlio -processo figlio comunica col cliente tramite pipe dedicata e serve le sue richieste -tra queste c'è anche la richiesta di uscire dal programma("exit").. il problema mio era che se il server principale viene chiuso malamente,deve gestire l'interruzione e avvertire i client ancora connessi della sua ahimè disdicevole dipartita MA,se il client quando decide di andarsene con la "exit" avverte il processo figlio,il server non saprà mai chi avvertire sulla gestione di un ctrl-c improvviso,perchè a lui l'informazione della uscita del client non può arrivare tramite il figlio(e qui disperandomi e confondendomi ho fatto la cazzata della variabile globale descritta sopra..) l'informazione non arriva AMMESSO CHE se io server quando faccio un figlio per trattare l'ennesimo cliente metto sia il pid del figlio(me lo restituisce la fork no?) sia il pid del cliente (che me lo spedisce quando si logga) in una struttura dati,quando il mio povero figlio muore nella gestione della SIGCHLD tramite il pid del figlio accedo alla struttura dati creata in partenza ed elimino sia il pid del figlio sia il pid del client (e ringrazio ilsensine che mi ha instradato nella soluzione) DIMODOCHE',quando arriva un ctrl-c scorro la struttura dati e prima di morire definitivamente mando delle SIGINT ai pid client rimasti. stavolta spero di essere stato chiaro,e se avete da appuntare appuntatelo grazie ancora |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
nb comunque esiste un altro modo per inviare un segnale a tutti i (o determinati) child di un processo -- i process group: Codice:
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <signal.h> void process() { signal(SIGUSR1, SIG_DFL); while (1) { fprintf(stderr, "Processo %d\n", getpid()); sleep(1); } _exit(0); } void createChild() { pid_t c = fork(); if (c==0) process(); if (setpgid(c, getpid())<0) perror("setpgid"); } int main() { signal(SIGUSR1, SIG_IGN); if (setpgrp()<0) perror("setpgrp"); createChild(); createChild(); sleep(3); killpg(getpid(), SIGUSR1); fprintf(stderr, "Fatto.\n"); return 0; }
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Mar 2006
Messaggi: 131
|
ho tirato fuori una cosa del genere,arriva un SIGCHLD,entra in gioco questo gestore
nella struttura dati clienti sono presenti per ogni pointer nomecliente,pidcliente,pidfiglio li trovo con la waitpid e li azzero quando il server principale riceverà un ctrl-c scorrerà l'array e ucciderà tutti i pid nonzero che troverà sul suo cammino se i processi diventano molti,riconosco che è un pò pesante e servirebbe un process group void gestore2(int signal){ int status; pid_t figlio; figlio = wait(&status); int conta = 0; while(clienti[conta] != NULL){ if(clienti[conta]->pidson == figlio){ clienti[conta]->pid = 0; clienti[conta]->pidson = 0; } conta++ } } potrebbe andare? |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Non che miaccia molto come è scritto, ma dovrebbe.
Continuo a dire che dovrtesti usare i thread.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#10 |
Member
Iscritto dal: Mar 2006
Messaggi: 131
|
la wait della procedura di gestione del segnale SIGCHLD che ho riportato sopra adesso continua a resituirmi -1 al posto del pid del figlio appena uscito dal programma
se stampo su schermo errno è 10, cioè che "Il processo chiamante non ha nessun figlio inaspettato" non capisco da cosa possa venir fuori una cosa del genere,soprattutto perchè in precedenza andava,l'unica cosa è che ho aggiunto un processo in più sopra che esce e lascia che il processo padre con i suoi figli girino in background...c sto impazzendo sopra! ![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:48.