|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Utilizzo di semafori sotto linux
Salve a tutti, dovrei realizzare entro pochi giorni un programma che mi serve per l'università nel quale c'è bisogno che io faccia uso di semafori per sincronizzare dei processi. Questo programma deve essere sviluppato in ambiente linux. Ho cercato di documentarmi riguardo la creazione e l'utilizzo dei semafori e ho capito che per dichiarare dei semafori bisogna richiamare la funzione:
int semget(key_t key, int nsems, int flag) Il mio dubbio riguarda il parametro key. Non ho capito dove prenderlo e qual'è il suo scopo. Poichè è una questione urgente mi auguro che mi rispondiate al + presto, grazie. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
E' un numero unico che identifica il semaforo (in generale un oggetto condiviso) nell'intero sistema.
Devi usare la stessa key nelle varie applicazioni per utilizzare lo stesso semaforo. Scegli tu un valore.
__________________
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 |
|
Senior Member
Iscritto dal: Dec 2001
Città: Roma
Messaggi: 542
|
In pratica il tipo key_t è una ridefinizione del tipo int, devi assegnare tu un valore arbitrario al semaforo, che come ti ha detto ilsensine dovrai utilizzare nel tuo programma per riferirti a quel semaforo quando dovrai farci delle operazioni.
Infatti alla chiamata semop, che serve a cambiare il valore dei semafori, devi passargli quel valore per dirgli su quale semaforo operare. Ora non mi ricordo la sintassi, ma dovrebbe essere proprio il primo parametro.
__________________
Il 90% dei problemi di un computer si trova tra la tastiera e la sedia. XP2500+@3200+|A7N8X Deluxe|1,25 GB DDR400|Radeon 9550|HD 160+320 GB SATA|WinXP Pro|Fastweb 6 Mb/s |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
__________________
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: Dec 2001
Città: Roma
Messaggi: 542
|
Quote:
oooooooops....mi sa che hai ragione....volevo far vedere che ne sapevo qualcosa anche io ma ho cannato l'esempio...
__________________
Il 90% dei problemi di un computer si trova tra la tastiera e la sedia. XP2500+@3200+|A7N8X Deluxe|1,25 GB DDR400|Radeon 9550|HD 160+320 GB SATA|WinXP Pro|Fastweb 6 Mb/s |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
ragazzi vi ringrazio. quindi e ho ben capito dovrei fare una cosa di questo genere:
Codice:
int mutex; mutex=semget(0, 1, IPC_CREATE); /*creo l'insieme di semafori */ int semctl(int semid, int sem_num, int command, union semun ctl_arg); ora se ho ben capito i primi due parametri sono rispettivamente il valore restituito da semget e la key che ho passato a semget, ma gli altri due parametri, cioè command e semnum, cosa sono e come li ottengo? io dovrei inizializzare il semaforo al valore 2 in modo tale che entrino nella sezione critica due processi alla volta, come devo fare? inoltre per effettuare le operazioni di wait e signal su questo semaforo come devo fare? ragazzi vi ringrazio per la vostra disponibilità; rispondendomi mi state facendo un grossissimo favore, grazie! Ultima modifica di VegetaSSJ5 : 18-03-2004 alle 15:12. |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Guarda caso, il valore "0" coincide con IPC_PRIVATE (v. man semget e /usr/include/bits/ipc.h ) Hai a disposizione 2^32 valori, proprio 0 dovevi prendere?
__________________
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: Dec 2001
Città: Roma
Messaggi: 542
|
Quote:
Stavolta mi sono documentato... alla semctl devi passare nell'ordine: - identificativo del semaforo (o meglio dell'array di semafori) restituito dalla semget - numero del semaforo nell'array di semafori su cui eseguire l'operazione - Tipo di comando - parametri del comando Quando tu chiami la semget come secondo parametro specifichi quanti semafori vuoi creare, e nella semctl devi indicare su quale operare (con 0 indichi il primo, con 1 il secondo ecc.). La key serve solo nell'invocazione della semget, poi ti serve l'handle restituita dalla funzione. I tipi di comando possono essere questi (i più comuni): - IPC_RMID: per eliminare l'array di semafori identificato da semid; gli altri parametri vengono ignorati - GETALL: per leggere il valore di tutti i semafori nell'array, i valori vengono copiati in un buffer che il programmatore dovrà creare e passare alla funzione nel campo arg (l'ultimo). - SETALL: setta i valori di tutti i semafori dell'array leggendo i valori da un buffer precedentemente impostato dal programmatore e passato come ultimo parametro. - GETVAL: la funzione restituisce il valore del semaforo specificato dal numero passato come secondo argomento, l'ultimo parametro viene ignorato - SETVAL: imposta il valore del semaforo specificato da sem_num uguale al valore passato come ultimo parametro.
__________________
Il 90% dei problemi di un computer si trova tra la tastiera e la sedia. XP2500+@3200+|A7N8X Deluxe|1,25 GB DDR400|Radeon 9550|HD 160+320 GB SATA|WinXP Pro|Fastweb 6 Mb/s Ultima modifica di gabriele81 : 18-03-2004 alle 15:28. |
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
x ilsensine mamma mia che sfortuna che ho! proprio quello ho beccato.... x gabriele81 ti ringrazio molto ora è tutto più chiaro. dunque dovrei fare così: Codice:
int mutex; mutex=semget(1367, 1, IPC_CREATE); /*creo l'insieme di semafori */ semctl(mutex, 0, SETVAL, 2); /*inizializzo a due l'unico semaforo che ho creato semaforo */ |
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Dec 2001
Città: Roma
Messaggi: 542
|
Quote:
La semctl restituisce -1 in caso di errore, oppure il valore del semaforo specificato se come comando hai messo GETVAL, negli altri casi un valore positivo. Quando la invochi ti conviene fare un check sul valore restituito, se è < 0 lanci un errore (o un segnale o quello che ti fa più comodo).
__________________
Il 90% dei problemi di un computer si trova tra la tastiera e la sedia. XP2500+@3200+|A7N8X Deluxe|1,25 GB DDR400|Radeon 9550|HD 160+320 GB SATA|WinXP Pro|Fastweb 6 Mb/s |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
perfetto. ragazzi grazie a tutti, cmq credo in questi giorni di avere di nuovo bisogno di voi per cui occhio a questo thread. ciao!
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
ragazzi come non detto, rieccomi qua. dunque spiegamo il problema: io devo creare 2*N (con N dato in input) processi e li devo mettere in attesa ad un semaforo. io ho scritto questo, ma non so come devo usare semop(...) per effettuare le wait e le signal:
Codice:
void genera_giocatori (int N) {
pid_t giocatori[2*N];
int i=0;
int AccessoAlTavolo;
AccessoAlTavolo=semget(200, 1, IPC_CREAT);
semctl(AccessoAlTavolo, 0, SETVAL, 0);
for (i=0; i<2*N; ++i) {
pid_t pid= fork();
if (pid!=0) giocatori[i]=pid;
else if (pid==0) WAIT SEMAFORO ACCESSO AL TAVOLO;
else {
perror("Si è verificato un errore durante la creazione dei processi giocatori");
exit(1);
}
}
}
inoltre ho un'altra domanda: data l'istruzione Codice:
pid_t aaa; aaa=fork(); Codice:
pid_t arbitro; arbitro=fork(); if (arbitro==0) genera_giocatori(n); Ultima modifica di VegetaSSJ5 : 19-03-2004 alle 15:36. |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Napoli
Messaggi: 543
|
Quote:
Rotfl mi ha fatto divertire molto questo intervento |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
ragazzi il problema precedente è stato risolto, ma ora ho bisogno di nuovo di una vostra piccola mano:
allora, ci sono dei processi giocatori che giocano a due a due e poi alla fine della partita si mettono in pausa con la funzione pause(). Poi c'è il processo arbitro che deve fare dei conti e poi prendere i due processi che hanno ottenuto il punteggio migliore. Ho individuato tali processi e ho ucciso gli altri con kill(PID, SIGKILL), a questo punto dovrei svegliare i due processi che hanno ottenuto punteggio migliore e portarli ad una funzione seconda_fase(). Come faccio a svegliare questi processi e a portarli alla funzione seconda_fase()? |
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
[EDIT]
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
|
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Normalmente SIGUSR1 causa la terminazione del processo, a meno che non gli assegni una funzione per gestirlo. v. man signal (o sigaction) per informazioni su come assegnare un handler a un segnale. A te basta una funzione vuota, che evita la terminazione del processo.
__________________
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 |
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Quote:
|
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
|
|
|
|
|
|
|
#20 | ||
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Quote:
Codice:
#include <signal.h>
#include <unistd.h>
int last_signal = 0;
void null_sighandler(int signum) {
last_signal = signum;
signal(signum, null_sighandler);
}
void do_pause() {
while(last_signal!=SIGUSR1)
pause();
last_signal = 0;
}
int main() {
signal(SIGUSR1, null_sighandler);
(...)
do_pause();
}
__________________
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 |
||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:09.



















