Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it L'avatar di ibykos
    Registrato dal
    Feb 2005
    Messaggi
    201

    [C] funzionamento dell'oggetto mutex

    In che modo funziona l'oggetto restituito dalla CreateMutex () in ambiente windows?
    Mi interessa conoscere il suo comportamento quando chiamo la WaitForSingleObject e quando chiamo la ReleaseMutex.
    Facoltativo: cosa succede quando chiamo la CloseHandle? :-)
    Non mi interessa il comportamento "a scatola chiusa" ma piuttosto quello che succede a livello di contatori e cose simili.
    In buona sostanza vorrei capire la differenza tra un mutex ed un semaforo in widows.

  2. #2
    Utente di HTML.it L'avatar di ibykos
    Registrato dal
    Feb 2005
    Messaggi
    201
    up

  3. #3
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,782
    Tutto sulla sincronizzazione in ambiente windows

    Mutex
    Semafori
    Sezioni critiche

    I Mutex sono binari e vengono usati essenzialmente per gestire mutue esclusioni. Non vi è un esplicito contatore associato al mutex, solo libero/occupato. A seguito di WaitforSingleObject multipli da parte di un thread (permessi dal SO e non bloccanti per evitare un deadlock) quello stesso thread deve chiamare uno stesso numero di ReleaseMutex per liberare il mutex. Esiste quindi un contatore implicito visibile solo all'interno del thread per gestire questa particolare situazione. Questo contatore implicito non è visibile agli altri thread e cessa di esistere quando il controllo è dato ad un altro thread.
    After a thread obtains ownership of a mutex, it can specify the same mutex in repeated calls to the wait-functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. To release its ownership under such circumstances, the thread must call ReleaseMutex once for each time that the mutex satisfied the conditions of a wait function.
    I semafori invece hanno associato un numero intero >=0 e non un binario. Ogni WaitForSingleObject decrementa il contatore e ogni ReleaseSemaphore lo incrementa. Se il contatore è 0 allora il semaforo è occupato, libero se >0. Considera che nella terminologia MS "signaled" è inteso come libero.
    Nel caso dei semafori il contatore è parte della risorsa semaforo ed è visibile a tutti i thread.
    A thread that owns a mutex object can wait repeatedly for the same mutex object to become signaled without its execution becoming blocked. A thread that waits repeatedly for the same semaphore object, however, decrements the semaphore's count each time a wait operation is completed; the thread is blocked when the count gets to zero. Similarly, only the thread that owns a mutex can successfully call the ReleaseMutex function, though any thread can use ReleaseSemaphore to increase the count of a semaphore object.
    Le sezioni critiche (Critical Section) sono del tutto simili ai mutex ma possono essere usati solo dai thread di uno stesso processo. Il mutex è interprocess (poi assegnare un nome al mutex per permettergli di essere referenziarlo da un altro processo!), la sezione critica è visibile solo all'interno di un unico processo ed è quindi più efficiente di un mutex.
    Leggi il REGOLAMENTO!

    E' molto complicato, un mucchio di input e output, una quantità di informazioni, un mucchio di elementi da considerare, ho una quantità di elementi da tener presente...
    Drugo

  4. #4
    Utente di HTML.it L'avatar di ibykos
    Registrato dal
    Feb 2005
    Messaggi
    201
    Ti ringrazio molto.

    quindi un codice di questo tipo

    codice:
    globale:
    
    a=TRUE;
    b=FALSE;
    
    Thread 1:
    
    while (TRUE){
    WaitForSingleObject(a,INFINITE);
    usaRisorsaCondivisa();
    ReleaseMutex(b);
    }
    
    Thread 2:
    
    while(TRUE){
    
    WaitForSingleObject(b,INFINITE);
    usaRisorsaCondivisa();
    ReleaseMutex(a);
    }
    Dovrebbe permettere ai due thread di accedere alternativamente ad una risorsa.
    Però ho osservato che la cosa non succede , almeno in questo codice, perché?

    codice:
    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    DWORD WINAPI concurrent (void *);
    
    HANDLE b,
           a,
           conc;
           
    int id;
    LPDWORD ID=(LPDWORD)&id;
           
    int main (){
        
        char c=' ';
        
        b=CreateMutex(NULL,TRUE,"b");
        a=CreateMutex(NULL,FALSE,"a");
        
        conc = CreateThread(NULL,0,concurrent,NULL,0,ID);
        
        if (conc==NULL)
            printf("creazione thread fallita\n");
        
        while (TRUE){
            WaitForSingleObject(a,INFINITE);   
            printf ("a\n");
            ReleaseMutex(b);
        }    
        
        return 0;
    }    
    
    DWORD WINAPI concurrent (void * dati){
        
        printf ("inizio TRUE=%d\n",TRUE);
        
        while (TRUE){
            WaitForSingleObject(b,INFINITE);
            printf ("b\n");
            ReleaseMutex(a);
        }    
        
    }

  5. #5
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,782
    In effetti i mutex di win non sono adeguati per fare quello che chiedi. Sono perfetti per garantire una mutua esclusione per l'accesso ad una risorsa comune (ad esempio una variabile globale ai thread). In questo caso si usa un solo mutex inizializzato a FALSE e la sezione critica di accesso alla variabile ha come prologo la waitforsingleobject e come epilogo la releasemutex.


    A=FALSE;
    var globale

    Thread1:
    waitforsingleobject(A)
    accesso alla var globale
    releasemutex(A)

    Thread2:
    waitforsingleobject(A)
    accesso alla var globale
    releasemutex(A)


    Il problema del mutex nel tuo caso è che se nello stesso thread eseguo più waitforsingleobject senza eseguire la relativa release non mi blocco! Questa è una condizione eccezionale che non dovrebbe mai accadere con i mutex. In più per tornare ad essere bloccante devo eseguire tante release quante wait. La scelta di non bloccarsi in questa situazione è stata fatta per evidare possibili deadlock.
    Considera per esempio il solo tuo thread concurrent ed ipotizza che quando entri la prima volta b sia libero. Questo esgue un ciclo continuo wait(a)..release(b). A seconda della velocita reletiva dei thread, concurrent puo' eseguire piu cicli consecutivi senza bloccarsi. Per tornare a bloccarsi deve aspettare uno stesso numero di release(a) da parte del thread principale...
    Non so se non riuscito ad essere vagamente chiaro.
    Tutto questo per dirti che in questo caso il costrutto giusto è il semaforo. Con i semafori wait multiple sono bloccanti.

    codice:
    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    DWORD WINAPI concurrent (void *);
    
    HANDLE b,
           a,
           conc;
           
    int id;
    LPDWORD ID=(LPDWORD)&id;
           
    int main (){
        
        char c=' ';
        
        a=CreateSemaphore(NULL,1,1,"a");
        b=CreateSemaphore(NULL,0,1,"b");
        
        conc=CreateThread (NULL,0,concurrent,NULL,0,ID);
        
        if (conc==NULL)
            printf("creazione thread fallita\n");
        
        sleep(1000);
        while (TRUE){
            //printf ("in attesa per A\n");
            WaitForSingleObject(a,INFINITE);   
            printf ("A\n");
            ReleaseSemaphore(b,1,NULL);
        }    
        
        return 0;
    }    
    
    DWORD WINAPI concurrent (void * dati){
        
        while (TRUE){
            //printf ("in attesa per B\n");
            WaitForSingleObject(b,INFINITE);
            printf ("B\n");
            ReleaseSemaphore(a,1,NULL);
        }    
        
    }
    In sostanza usa i mutex solo per l'accesso a sezioni critiche in mutua esclusione. Per sincronizzazioni di tipo diverso usa i semafori.
    Leggi il REGOLAMENTO!

    E' molto complicato, un mucchio di input e output, una quantità di informazioni, un mucchio di elementi da considerare, ho una quantità di elementi da tener presente...
    Drugo

  6. #6
    Utente di HTML.it L'avatar di ibykos
    Registrato dal
    Feb 2005
    Messaggi
    201
    Perfetto, grazie!

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.