信号量在 C 中不起作用,为什么?




首先,我是意大利人,很抱歉我的英语不好
无论如何,我应该做这个练习:
用C语言编写一个生成线程的程序。主线程显示从1到9的奇数,线程显示从2到10的偶数。将main和线程与信号量同步"

我用这种方式编写了伪代码:

//semaphores
semParent = free
semChild = busy
main
  generate thread "child"
  for i=1 to 9 step 2
    P(semParent)
    print i
    V(semChild)
  end for
end main
child
  for i=2 to 10 step 2
    P(semChild)
    print i
    V(semParent)
end child

这就是我在C:中实现的方式

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t semParent;
pthread_mutex_t semChild = PTHREAD_MUTEX_INITIALIZER;
void* functionChild (void* arg) {
    for(int i=2; i<=10; i+=2) {
        pthread_mutex_lock(&semChild);
        printf("CHILD: %dn",i);
        pthread_mutex_unlock(&semParent);
    }
    return NULL;
}
int main(void) {    
    pthread_t child;
    pthread_create(&child, NULL, &functionChild, NULL);
    pthread_mutex_init(&semParent, NULL);
    for(int i=1; i<=9; i+=2) {
        pthread_mutex_lock(&semParent);
        printf("PARENT : %dn",i);
        pthread_mutex_unlock(&semChild);
    }
    pthread_join(child, NULL);
}

但是每当我运行程序时,输出总是不同的
怎么了

我在Windows 10 64位中使用CygWin64终端
提前谢谢。

pthread_mutex_t不是信号量(尽管如果执行"V"将信号量初始化为"free",则信号量可以用作互斥对象)。信号量API是sem_initsem_postsem_wait

通过在被另一个线程锁定的互斥体上使用pthread_mutex_unlock,您的程序正在触发未定义的行为。

这可能不是您现在遇到问题的原因,但您永远不应该在多线程程序中使用printf()。printf()写入缓冲区,并不总是立即打印到屏幕上。相反,您应该使用sprintf()并编写:

char buff[20];
sprintf("PARENT: %dn", i);
write(1, buff, strlen(buff));

我认为具有NULL属性的pthread_mutex_init(&semParent, NULL)PTHREAD_MUTEX_INITIALIZER具有相同的效果,即两个锁都被初始化为解锁。不过,你们的问题并没有严格意义上的关键部分。因此,正如@Serhio所提到的,一个更好的解决方案应该是条件变量。你也可以查看信号量http://www.csc.villanova.edu/~mdamian/threads/posixsem.html,它们提供了更大的自由度,还可以具有互斥的功能。

最新更新