使用信号量严格按顺序同步N个进程

时间:2017-11-07 08:15:03

标签: c multithreading synchronization semaphore

我遇到了Semaphore任务的简单问题。

我正在进行N处理(P1,P2,P3,P4 ...... Pn)。无论我以什么顺序创建线程,我都需要它们按照确切的顺序执行(P1,P2,P3,P4 ...... Pn)。我需要提供解决方案,我需要使用最小信号量。

使用Mutex会非常简单,但任务说"只使用信号量"。

我只使用一个信号量。同时,在条件下,如果订单号不等于您的ID号,只需解锁信号量并循环播放,直到订单号等于您的ID号。

我认为这个问题可能出现在" Spurious wakeups"。

这是我的代码:

sem_t semvar;
int order = 0;

void *sayHello(void *thread_id){
    int *my_id = (int *) thread_id;

    while(1)
    {
        // take semaphore and close critical zone to read order variable to recognize who's on turn!
        sem_wait(&semvar);
            if(*my_id == order)
            {
                // if I'm on turn, then I shout my number and set order variable to someone behind me
                printf("I'm thread no.: %d\n", *my_id);
                order++;
                break;
            }
        // release semaphore if I'm not on turn!
        sem_post(&semvar);
    }
    // release semaphore if it was my turn, I shout my number and gonna end (die)!
    sem_post(&semvar);

    pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
    int numbOfThreads = 13;
    int *thread_id[numbOfThreads];
    int new_thread, i;

    pthread_t threads[numbOfThreads];


    // generating thread numbers --> NOTE: you need this, if you use random thread generating!!!
    for(i = 0; i < numbOfThreads; i++)
    {
        thread_id[i] = (int *) malloc(sizeof(int));
        *thread_id[i] = i;
    }

    // random thread generating for testing to make sure it works
    pthread_create(&threads[10], NULL, sayHello, (void *) thread_id[10]);
    pthread_create(&threads[12], NULL, sayHello, (void *) thread_id[12]);
    pthread_create(&threads[8], NULL, sayHello, (void *) thread_id[8]);
    pthread_create(&threads[3], NULL, sayHello, (void *) thread_id[3]);
    pthread_create(&threads[5], NULL, sayHello, (void *) thread_id[5]);
    pthread_create(&threads[1], NULL, sayHello, (void *) thread_id[1]);
    pthread_create(&threads[0], NULL, sayHello, (void *) thread_id[0]);
    pthread_create(&threads[4], NULL, sayHello, (void *) thread_id[4]);
    pthread_create(&threads[7], NULL, sayHello, (void *) thread_id[7]);
    pthread_create(&threads[6], NULL, sayHello, (void *) thread_id[6]);
    pthread_create(&threads[2], NULL, sayHello, (void *) thread_id[2]);
    pthread_create(&threads[9], NULL, sayHello, (void *) thread_id[9]);
    pthread_create(&threads[11], NULL, sayHello, (void *) thread_id[11]);

/*
    // automatic thread generating
    for(i = 0; i < numbOfThreads; i++)
    {
        thread_id[i] = (int *) malloc(sizeof(int));
        *thread_id[i] = i;
        new_thread = pthread_create(&threads[i], NULL, sayHello, (void *) thread_id[i]);

        if(new_thread)
        {
            printf("Error has occured");
            exit(-1);
        }
    }
*/

    // do not end main function before all the threads are done with work!
    for(i = 0; i < numbOfThreads; i++)
    {
        pthread_join( threads[i], NULL);
    }
    printf("All the threads are gone!");

    return 1;
}

0 个答案:

没有答案