Semaphore与多线程中的条件变量?

时间:2013-09-04 08:15:50

标签: c multithreading pthreads mutex semaphore

问题:我必须增加x1和x2变量,这应该由不同的线程完成,并且在两个变量的上一个增量都没有完成之前,不应该调用两个变量的下一个增量。

问题:

x1 =  0;  x2 = 0;

x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 1 and x2 = 1 
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 2 and x2 = 2 
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 3 and x2 = 3 
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 4 and x2 = 4
    …
    …
    …
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 10 and x2 = 10

close the threads

建议的解决方案使用pthread条件:初始化4个互斥锁和4个条件变量,并使用2个互斥锁来锁定主函数并为每个线程休息。两个线程都将等待main函数传递condtion信号以调用它们,并且在计算之后,它们将信号传递回主线程以进一步移动。提供1秒的睡眠,要求线程正确调用并准备接收并在计算后返回信号。

Pthread条件代码:

    #include <stdio.h>
    #include <pthread.h>

    pthread_t pth1,pth2;
    //Values to calculate
    int x1 = 0, x2 = 0;

    pthread_mutex_t m1, m2, m3, m4 = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t c1, c2, c3, c4 = PTHREAD_COND_INITIALIZER;

    void *threadfunc1(void *parm)
    {
        pthread_mutex_lock(&m1);
        for (;;) {
            pthread_cond_wait(&c1, &m1);
            x1++;
            pthread_mutex_lock(&m3);
            pthread_cond_signal(&c3);
            pthread_mutex_unlock(&m3);
        }
        pthread_mutex_unlock(&m1);
        return NULL ;
    }
    void *threadfunc2(void *parm)
    {
        pthread_mutex_lock(&m2);
        for (;;) {
            pthread_cond_wait(&c2, &m2);
            x2++;
            pthread_mutex_lock(&m4);
            pthread_cond_signal(&c4);
            pthread_mutex_unlock(&m4);
        }
        pthread_mutex_unlock(&m2);
        return NULL ;
    }

    int main () {
        pthread_create(&pth1, NULL, threadfunc1, "foo");
        pthread_create(&pth2, NULL, threadfunc2, "foo");
        sleep(1);
        int loop = 0;
        pthread_mutex_lock(&m3);
        pthread_mutex_lock(&m4);
        while (loop < 10) {
            // iterated as a step
            loop++;
            printf("Initial   : x1 = %d, x2 = %d\n", x1, x2);
            pthread_mutex_lock(&m1);
            pthread_cond_signal(&c1);
            pthread_mutex_unlock(&m1);
            pthread_mutex_lock(&m2);
            pthread_cond_signal(&c2);
            pthread_mutex_unlock(&m2);
            pthread_cond_wait(&c3, &m3);
            pthread_cond_wait(&c4, &m4);
            printf("Final   : x1 = %d, x2 = %d\n", x1, x2);
        }
        printf("Result   : x1 = %d, x2 = %d\n", x1, x2);
        pthread_mutex_unlock(&m3);
        pthread_mutex_unlock(&m4);
        pthread_cancel(pth1);
        pthread_cancel(pth2);
        return 1;
    }

使用信号量建议的解决方案:初始化4个信号量并调用单独的线程以单独增加变量。 2个信号量,用于将消息传递给线程以开始递增; 2个信号量,用于将消息传递到主线程,完成递增。主线程将等待来自两个子线程的信号量发布,显示两个变量的增量完成,然后主线程将消息传递给两个子线程 线程允许进一步递增。

信号量代码:

    #include <stdio.h>
    #include <pthread.h>
    #include <semaphore.h>

    //Threads
    pthread_t pth1,pth2;

    //Values to calculate
    int x1 = 0, x2 = 0;

    sem_t c1,c2,c3,c4;

    void *threadfunc1(void *parm)
    {
        for (;;) {
            x1++;
            sem_post(&c1);
            sem_wait(&c3);
        }
        return NULL ;
    }

    void *threadfunc2(void *parm)
    {
        for (;;) {
            x2++;
            sem_post(&c2);
            sem_wait(&c4);
        }
        return NULL ;
    }

    int main () {
        sem_init(&c1, 0, 0);
        sem_init(&c2, 0, 0);
        sem_init(&c3, 0, 0);
        sem_init(&c4, 0, 0);
        pthread_create(&pth1, NULL, threadfunc1, "foo");
        pthread_create(&pth2, NULL, threadfunc2, "foo");
        sem_wait(&c1);
        sem_wait(&c2);
        sem_post(&c3);
        sem_post(&c4);
        int loop = 0;
        while (loop < 8) {
            // iterated as a step
            loop++;
            printf("Initial   : x1 = %d, x2 = %d\n", x1, x2);
            sem_wait(&c1);
            sem_wait(&c2);
            printf("Final   : x1 = %d, x2 = %d\n", x1, x2);
            sem_post(&c3);
            sem_post(&c4);
        }
        sem_wait(&c1);
        sem_wait(&c2);
        sem_destroy(&c1);
        sem_destroy(&c2);
        sem_destroy(&c3);
        sem_destroy(&c4);
        printf("Result   : x1 = %d, x2 = %d\n", x1, x2);
        pthread_cancel(pth1);
        pthread_cancel(pth2);
        return 1;
    }

请建议我,哪一种更好的实施方式或哪些方面可以改进?任何建议都会有所帮助。提前致谢。 对不起,如果我重复自己,因为,这个问题已成为我的噩梦..请帮助。

0 个答案:

没有答案