Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

semaphore

Status
Not open for further replies.

tzzdvd

Programmer
Aug 17, 2001
52
IT
Hi,
I try to use cygwin and linux expecting to have the same result but I discover this "problem".
I try to learn about thread and semaphore and I write this simple program

Code:
struct sembuf lock_it;
struct sembuf unlock_it;
int a = 0;
int mutex;

void *thRoutine1(void *arg)
{
    while(1)
    {
        semop(mutex, & lock_it, 1);
        printf ("\nSemaphore locked by 'Routine 1'\n");
        fflush(stdout);
        a ++;
        printf ("\n 'Routine 1' unlock Semaphore");
        fflush(stdout);
        semop(mutex, & unlock_it, 1);
    }
}

void *thRoutine2(void *arg)
{
    while(1)
    {
        semop(mutex, & lock_it, 1);
        printf ("\nSemaphore locked by 'Routine 2'\n");
        fflush(stdout);
        a += 10000;
        printf ("\n 'Routine 1' unlock Semaphore");
        fflush(stdout);
        semop(mutex, & unlock_it, 1);
    }
}

void *thRead(void *arg)
{
    while(1)
    {
        semop(mutex, & lock_it, 1); // faccio un lock sulla risorsa
        printf ("\nSemaphore locked by 'Routine Read'\n");
        fflush(stdout);
        printf("\n          a = %d; ", a);
        fflush(stdout);
        printf ("\n 'Routine Read' unlock Semaphore");
        fflush(stdout);
        semop(mutex, & unlock_it, 1); // faccio un lock sulla risorsa
    }
}

int main()
{
pthread_t       th1, th2, thR;
key_t           unique_key;
union semun     options;
    unique_key = ftok(".", 'r'); 
    printf("\n Unique_key = %d", unique_key);
    fflush(stdout);
    if ( (mutex = semget(unique_key, 1, IPC_CREAT | IPC_EXCL | 0x0666)) == -1)
    {
        printf ("\nError");
        fflush(stdout);
        abort();
    }
    printf ("\n\nSemaphore ID = %d\n", mutex);
    fflush(stdout);
    options.val = 1;
    semctl(mutex, 0, SETVAL, options);
    // for lock operation
    lock_it.sem_num = 0;    
    lock_it.sem_op  = -1;   
    lock_it.sem_flg = IPC_NOWAIT;
    // for unlock operation
    unlock_it.sem_num = 0;   
    unlock_it.sem_op  = 1;   
    unlock_it.sem_flg = IPC_NOWAIT; 
    pthread_create( & th1, NULL, thRoutine1, NULL);
    pthread_create( & th2, NULL, thRoutine2, NULL);
    pthread_create( & thR, NULL, thRead, NULL);
    while(1) ;          
    return 0;
}

I compiled it under cygwin and I receve what I expect i.e. in a random way all the three thread lock the semaphore, update the variable and unlock the semaphore. The access to the resource (the 'a' variable) is equally distribuited between the three thread.
Then I compiled under Fedora Core 3 exaclty the same program and I noticed that if i.e. Routine 1 passes the semaphore once, then about 300-400 time again use the resource. If another thread is able to gain the resource, then that thread gain it again for a lot of times.
I expected, as in cygwin, that the access to the resource would be again equally distribuited.
Did I make any mistake?

I apologize if this is not the right forum to use.
If it isn't, please tell me where I can post my question.

Thank's of all.
Davide

 
It isn't a C/C++ question. The code isn't really what he's asking about. Cygwin is just an emulator, but the stuff run under cygwin uses windows processes. The scheduling scheme for the two systems is different. The big thing about synchrons objects is that unless you impose some order of your own, then who ever "gets there first" wins.

Most process schedualing schemes are based on:
Round Robin - which is basically first in, first out
Shortest Process next - I give priority to the task that will will goble the least CPU based on how it's performed in the past (during this execution). So, if something blocks for I/O a lot then it gets priority, because if it slows down the user will be unhappy, besides this will only take a minute and the next process won't know the difference...
And few complicated premptive schedualers that care about things like how crtical is the task to the user, what it's CPU cycles are spent doing, is the process I/O bound or CPU bound?

The long and short is you can't know which thread, process or other unit of execution will gain the CPU next, that is why semaphores, mutexs, conditon variables and other synchronization tasks are so important. You can impose the order fairly easily with semaphore, but in most cases you really don't care as long as they all aren't trying to access the resource at the same time.

[plug=shameless]
[/plug]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top