了解C语言中的信号量

时间:2016-05-13 04:34:50

标签: c mutex semaphore

我已经在C中成功实现了Mutex锁和条件变量锁,并尝试使用信号量实现相同的功能。下面是我的代码,但在执行时,输出总是24而不是12.帮我理解如何使用信号量。

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

#define NUM_THREADS  2
#define TCOUNT 12
#define COUNT_LIMIT 12

int count = 0;
sem_t sem;

void *dum(void *t_id){
    long id = long(t_id);
    for (int i = 0; i < TCOUNT; i++) {
        sem_wait(&sem);
        count++;
        sem_post(&sem);
        printf("In Dum(). Count :: %d. Thread :: %ld \n", count, id);
    }
    pthread_exit(NULL);
}

int main (int argc, char *argv[]) {
    int i;
    long t1=1, t2=2;
    sem_init(&sem, 0, 1);
    pthread_t threads[NUM_THREADS];
    pthread_create(&threads[1], NULL, dum, (void *)t1);
    pthread_create(&threads[2], NULL, dum, (void *) t2);
    for (i=1; i<=2; i++) {
        pthread_join(threads[i], NULL);
    }
    printf ("Main(): Waited on %d  threads. Done.\n", NUM_THREADS);
    printf ("Count should be 12. Actual Count: %d. \n", count);
    pthread_exit(NULL);
}

输出:

In Dum(). Count :: 1. Thread :: 1 
In Dum(). Count :: 2. Thread :: 1 
In Dum(). Count :: 3. Thread :: 1 
In Dum(). Count :: 4. Thread :: 1 
In Dum(). Count :: 5. Thread :: 1 
In Dum(). Count :: 6. Thread :: 1 
In Dum(). Count :: 7. Thread :: 1 
In Dum(). Count :: 8. Thread :: 1 
In Dum(). Count :: 9. Thread :: 1 
In Dum(). Count :: 10. Thread :: 1 
In Dum(). Count :: 11. Thread :: 1 
In Dum(). Count :: 13. Thread :: 1 
In Dum(). Count :: 13. Thread :: 2 
In Dum(). Count :: 14. Thread :: 2 
In Dum(). Count :: 15. Thread :: 2 
In Dum(). Count :: 16. Thread :: 2 
In Dum(). Count :: 17. Thread :: 2 
In Dum(). Count :: 18. Thread :: 2 
In Dum(). Count :: 19. Thread :: 2 
In Dum(). Count :: 20. Thread :: 2 
In Dum(). Count :: 21. Thread :: 2 
In Dum(). Count :: 22. Thread :: 2 
In Dum(). Count :: 23. Thread :: 2 
In Dum(). Count :: 24. Thread :: 2 
Main(): Waited on 2  threads. Done.
Count should be 12. Actual Count: 24. 

1 个答案:

答案 0 :(得分:1)

正如kcraigie所说,你正在为线程数组索引错误。最好通过指针传递t1和t2:

void *dum(void *t_id)
{
    long id = *(long*)t_id;

pthread_create(&threads[0], NULL, dum, (void *) &t1);
pthread_create(&threads[1], NULL, dum, (void *) &t2);
for (i=0; i<2; i++) 
{
    pthread_join(threads[i], NULL);
}

同样在你的线程中你锁定信号量,增加计数并释放信号量,然后打印它。在您递增之后,无法保证您打印的值将是count的值。另一个线程可能已经这样做了。将printf放在信号量锁中:

sem_wait(&sem);
count++;
printf("In Dum(). Count :: %d. Thread :: %ld \n", count, id);
sem_post(&sem);

但是,否则计入24似乎是正确的行为。你有两个循环分布在2个线程上,每个循环迭代12次,加上一个计数。事实上,其中一个人首先完成其循环,然后是另一个,这可能是因为在主线程有机会启动线程2之前,首先启动的线程在单个时间片内完成所有工作。