|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Oct 1999
Città: Milano
Messaggi: 531
|
dubbi sul pause()...sotto unix
ragazzi non riesco a capire bene l utilizzo di questa funzione:quando metto un processo in pause, esso dovrebbe risvegliarsi alla ricezione di un segnale gestito da un apposita funzione ad esempio:
//da processo 1 ... signal(SIGUSR1,sveglio); pause(); ... //da altro processo ... kill(processo1,SIGUSR1); ... //il sig_handler ... void sveglio() { printf("mi sveglio\n"); return; } va bene cosi?dovrebbe ripartire il padre dove si era fermato? il fatto è che non sempre si sveglia...ad esempio, può succedere che quando va di nuovo in pausa nn si risveglia più! c è qualcuno che può aiutarmi?
__________________
Vintage signature: Abit nf7-s, Xp 2500+@2300mhz, 256 mb 418mhz cas2, geforce fx5700,S-ATA 160 Maxtor,Lg gsa 4120b...prima..ma ora..DELL INSPIRON 6400, ATI X1300... |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 1999
Città: Milano
Messaggi: 531
|
UP!!
__________________
Vintage signature: Abit nf7-s, Xp 2500+@2300mhz, 256 mb 418mhz cas2, geforce fx5700,S-ATA 160 Maxtor,Lg gsa 4120b...prima..ma ora..DELL INSPIRON 6400, ATI X1300... |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Posta un programmino completo e compilabile che consente di riprodurre il problema.
__________________
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 |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Oct 1999
Città: Milano
Messaggi: 531
|
http://forum.hwupgrade.it/showthread...hreadid=828647
una domandina facile facile...ma per fare ping pong tra due processi mi conviene usare i segnali? o meglio se faccio waitpid con un uso opportuno?
__________________
Vintage signature: Abit nf7-s, Xp 2500+@2300mhz, 256 mb 418mhz cas2, geforce fx5700,S-ATA 160 Maxtor,Lg gsa 4120b...prima..ma ora..DELL INSPIRON 6400, ATI X1300... |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Oct 1999
Città: Milano
Messaggi: 531
|
per farla semplice non funziona neanche questo:
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <sys/types.h> void sveglio() { printf("sveglia\n"); // raise(SIGCONT); } int main(){ int figlio; signal(SIGUSR1,sveglio); printf(" proviamo i pause, se arrivo alla fine allora funge altrimenti uccidere con ctrl+c\n"); figlio=fork(); if (figlio==0){ pause(); kill(getppid(),SIGUSR1); pause(); kill(getppid(),SIGUSR1); pause(); exit(0); }else{ sleep(1); kill(figlio,SIGUSR1); pause(); kill(figlio,SIGUSR1); pause(); kill(figlio,SIGUSR1); waitpid(figlio,NULL,NULL); printf("finito\n"); } }
__________________
Vintage signature: Abit nf7-s, Xp 2500+@2300mhz, 256 mb 418mhz cas2, geforce fx5700,S-ATA 160 Maxtor,Lg gsa 4120b...prima..ma ora..DELL INSPIRON 6400, ATI X1300... |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Qui funziona, ma per pura fortuna.
Il programma è suscettibile di una ovvia race condition se avviene un context switch tra una kill() e la successiva pause(): in questa situazione, un processo esegue una kill mentre l'altro ancora non è nello stato di pause, rendendo la kill totalmente inefficace. Posso simulare la race inserendo una sched_yield() tra una kill e la pause successiva.
__________________
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 |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
In parole povere:
Codice:
p1 p2 pause (switch su p2) kill (switch su p1??) kill pause pause bye
__________________
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 |
|
Senior Member
Iscritto dal: Oct 1999
Città: Milano
Messaggi: 531
|
in poche parole per far funzionare il ping pong fra i processi devo inserire degli sleep in modo tale da sincronizzare i due processi?...i
__________________
Vintage signature: Abit nf7-s, Xp 2500+@2300mhz, 256 mb 418mhz cas2, geforce fx5700,S-ATA 160 Maxtor,Lg gsa 4120b...prima..ma ora..DELL INSPIRON 6400, ATI X1300... |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Il problema è concettuale, non tanto implementativo. Il tuo errore è eseguire la kill senza essere sicuro dello stato in cui si trova l'altro processo. Visto che l'esecuzione è totalmente asincrona, non puoi essere sicuro dello stato in alcun modo ovvio.
Se vuoi fare un semplice ping-pong, usa i messaggi (msgsnd/msgrcv).
__________________
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 |
|
Senior Member
Iscritto dal: Oct 1999
Città: Milano
Messaggi: 531
|
il problema è che questo esercizio è relativo alla parte di sistemi operativi mod a...quindi nello scritto nn posso usare nozioni di sistemi b...noi facciamo l IPC V solo al secondo modulo...
devo passare lo scritto di mod a ma nel frattempo sto seguendo il b all università.... perciò posso usare solo segnali, wait....capito? ho provato ad usare delle sleep opportunamente messe e va tipo prima dei kill in modo tale che l altro processo vada in pause quando deve. E' sporco come metodo? considerando che i cambi di contesti avvengono sempre negli ordini di ms 1 secondo nella sleep è più che sufficiente non credi? fammi sapere ciao e grazie P.S. scusa per il disturbo!!!
__________________
Vintage signature: Abit nf7-s, Xp 2500+@2300mhz, 256 mb 418mhz cas2, geforce fx5700,S-ATA 160 Maxtor,Lg gsa 4120b...prima..ma ora..DELL INSPIRON 6400, ATI X1300... |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Una soluzione più pulita (relativamente) può essere questa: imponi che, quando viene svegliato da kill, il processo invii un feedback a chi lo ha svegliato (ad es. tramite SIGUSR2). Se il feedback non arriva entro un certo timeout, ritenti il primo kill.
__________________
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 |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Qualcosa di questo tipo insomma: (negherò fino alla morte di aver scritto questa porcheria
Codice:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
int killing;
void sveglio()
{
printf("sveglia\n");
}
void ack()
{
killing = 0;
}
void do_kill(pid_t pid)
{
killing = 1;
while(killing)
{
kill(pid, SIGUSR1);
// Se SIGUSR2 arriva durante usleep, questa si interrompe con EINTR
if(killing)
usleep(25000);
}
}
int main(){
int figlio;
signal(SIGUSR1,sveglio);
signal(SIGUSR2,ack);
printf(" proviamo i pause, se arrivo alla fine allora funge altrimenti uccidere con ctrl+c\n");
figlio=fork();
if (figlio==0){
pause();
kill(getppid(), SIGUSR2);
do_kill(getppid());
pause();
kill(getppid(), SIGUSR2);
do_kill(getppid());
pause();
kill(getppid(), SIGUSR2);
exit(0);
}else{
sleep(1);
do_kill(figlio);
pause();
kill(figlio, SIGUSR2);
do_kill(figlio);
pause();
kill(figlio, SIGUSR2);
do_kill(figlio);
waitpid(figlio,NULL,0);
printf("finito\n");
}
}
__________________
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 |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Oct 1999
Città: Milano
Messaggi: 531
|
secondo me la tua versione non è poi tanto diversa da quella con degli sleep opportunamente messi, in quanto a me gli sleep li fa sempre mentre a te solo nel caso in cui ti trovi a mandare il segnale prima che va in pause....giusto?
ti faccio vedere una mia versione funzionante anche se sporchissima! Codice:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void sveglio()
{
printf("sveglia\n");
// raise(SIGCONT);
}
int main(){
int figlio;
signal(SIGUSR1,sveglio);
printf(" proviamo i pause, se arrivo alla fine allora funge altrimenti uccidere con ctrl+c\n");
figlio=fork();
if (figlio==0){ //temporalmente(Sequenze)
pause(); /* 1 */
sleep(1); /* 3 */ //aspetto il padre(pause)
kill(getppid(),SIGUSR1); /* 4 */
pause(); /* 5 */
sleep(1); /* 6 */
kill(getppid(),SIGUSR1); // e via dicendo
pause();
exit(0);
}else{
sleep(1);
kill(figlio,SIGUSR1); /* 2 */
pause(); /* 3 */ //assicurato dallo sleep
sleep(1); /* 5 */
kill(figlio,SIGUSR1); /* 6 */
pause();
sleep(1);
kill(figlio,SIGUSR1);
waitpid(figlio,NULL,NULL);
printf("finito\n");
exit(0);
}
}
__________________
Vintage signature: Abit nf7-s, Xp 2500+@2300mhz, 256 mb 418mhz cas2, geforce fx5700,S-ATA 160 Maxtor,Lg gsa 4120b...prima..ma ora..DELL INSPIRON 6400, ATI X1300... Ultima modifica di Ricky : 07-12-2004 alle 17:53. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 02:03.



















