Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    Mutua Esclusione [Atomicità]

    Ho un dubbio riguardante la mutua esclusione delle operazioni.
    Operazioni di scrittura, come l'incremento di una variabile, sono atomiche di default?
    Può succedere che 2 o + processi incrementino nello stesso momento una determinata variabile?

    Nel mio programma ho una variabile saldo(di un processo fornitore), che viene incrementata dai processi figli ogni volta che questi terminano la gestione di un ordine. Devo prevedere qualche meccanismo di mutua esclusione?

  2. #2

    Re: Mutua Esclusione [Atomicità]

    Originariamente inviato da Fusic86
    Ho un dubbio riguardante la mutua esclusione delle operazioni.
    Operazioni di scrittura, come l'incremento di una variabile, sono atomiche di default?
    No. I tipi atomici che garantiscono lettura e scrittura atomica dipendono dalla piattaforma e dal linguaggio. Ad esempio, in C su macchine a 32 bit l'incremento di una variabile a 64 bit tipicamente non è atomico.
    Può succedere che 2 o + processi incrementino nello stesso momento una determinata variabile?
    Sì (ovviamente se il blocco di memoria in questione è condiviso ).
    Nel mio programma ho una variabile saldo(di un processo fornitore), che viene incrementata dai processi figli ogni volta che questi terminano la gestione di un ordine. Devo prevedere qualche meccanismo di mutua esclusione?
    Sì (anche se potrebbe essere non necessario, come detto sopra dipende dalla piattaforma e dal tipo di dato usato).
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    la piattaforma è ubuntu 13.04 a 64bit, il tipo di dato è un semplice int.

    In caso, qual'è lo strumento migliore da utilizzare in questi casi per garantire un accesso esclusivo?

  4. #4
    Il "normale" int in genere corrisponde alla word nativa dell'architettura*, e, almeno su x86 e derivati, consente lettura e scrittura atomica (a patto che l'intero in questione sia allineato); diverso il discorso per l'incremento, che, salvo casi particolari (istruzioni assembly con prefisso LOCK) non è atomico (prevede un fetch e uno store).

    In ogni caso, dato che individualmente lettura e scrittura sono atomiche, puoi usare un semaforo POSIX per evitare che più processi cerchino di aggiornare lo stesso dato contemporaneamente. La lettura invece la puoi lasciare libera, dato che, per un int allineato, non c'è la possibilità di leggere un dato scritto "a mezzo" (cosa che invece si può verificare per altri tipi di dato - in tal caso avresti bisogno di un semaforo "generale", da usare anche solo per la lettura).

    ---

    * in realtà su x86_64/Linux int è un intero a 32 bit anche se l'architettura è a 64 bit, ma va bene lo stesso.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    ok, ho provato con i semafori POSIX a fare il seguente nonchè stupido programmino:
    codice:
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/syscall.h>
    #include <semaphore.h>
    #include <stdint.h>
    
    #define MAXNUM 1000
    
    sem_t sem;
    
    int main(){
    	
    	sem_init(&sem,1,1);
    	
    	int pid;
    	int count;
    	int j;
    	count=0;
    	for(j=0;j<=1;j++){
    		pid=fork();
    		if(pid==0){/*figlo*/
    			int ID=j;
    			for (j=0;j<MAXNUM;j++) {
    					sem_wait(&sem);	 
    					count++;
    					sem_post(&sem);
    			}
    			printf("Numero raggiunto da %d: %d", j,count); 
    			exit(1);
    		}
    	}
    }
    ma mi da i seguenti errori in compilazione:

    codice:
    /tmp/ccpuI6kr.o: nella funzione "main":
    semafori.c: (.text+0x1d): riferimento non definito a "SEM_INIT"
    semafori.c: (.text+0x54): riferimento non definito a "sem_wait"
    semafori.c: (.text+0x62): riferimento non definito a "sem_post"
    collect2: error: ld returned 1 exit status
    cosa c'è che non va?

  6. #6
    Devi aggiungere -lpthreads alla riga di comando del compilatore; inoltre, sem deve essere situato in un blocco di memoria condivisa, altrimenti ogni figlio eredita una copia del semaforo...
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Originariamente inviato da MItaly
    inoltre sem deve essere situato in un blocco di memoria condivisa, altrimenti ogni figlio eredita una copia del semaforo...
    Scusa ma dichiarandolo globalmente non basta?

    Inoltre sul codice postato avevo sbagliato anche la posizione della variabile count, che doveva essere globale. Ora l`ho modificato dichiarando:
    int count=0;
    globalmente fuori dal main, ma non funziona. Ogni variabile si incrementa la sua copia senza andare a modificare la variabile globale e se faccio stampare count dal padre dopo che tutti i figli sono terminati, mi stampa 0, ovvero il valore di inizializzazione. (quindi non so nemmemno se il semaforo effettivamente funzioni o no)

  8. #8
    Originariamente inviato da Fusic86
    Scusa ma dichiarandolo globalmente non basta?
    No, stiamo parlando di processi, non di thread, per cui di default ognuno ha il suo spazio di indirizzi con la sua copia delle variabili, se vuoi avere roba condivisa devi chiederlo esplicitamente (al contrario di quanto accade con i thread).
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    eheh, purtroppo era esplicitamente richiesto l'uso di processi e non di thread.
    Quindi dovrei usare le funzioni shmget e shmat?
    Siccome non le ho mai usate e da una prima letta su internet non ci ho capito molto potresti farmi una panoramica?

  10. #10
    Inoltre...
    per quello che riguarda la variabile count, ho provato ad ovviare al problema lavorando sui puntatori ( e onestamente speravo di risolverlo), perchè si, ogni processo figlio eredita una sua copia del puntatore, ma tutti dovrebbero puntare allo stesso segmento di memoria che di fatto diventerebbe condivisa, ma così non è. Perchè?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.