2016-08-02 41 views
1


首先,我是意大利人,对于我的英语不好,感到抱歉。
无论如何,我应该这样做:
“在C中编写一个生成线程的程序,主要显示从1到9的奇数,线程显示从2到10的偶数。使主线程和线程同步信号灯”

我写这样的伪代码:信号量在C.中不起作用为什么?

//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: %d\n",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 : %d\n",i); 
     pthread_mutex_unlock(&semChild); 
    } 
    pthread_join(child, NULL); 
} 

但输出ALWA每当我运行程序时,ys都会有所不同。
有什么问题?

我在Windows 10 64位中使用CygWin64终端。
在此先感谢。

+0

为了实现单调增加的输出值,您应该将“stick”从一个线程反复传递给其他线程。寻找条件变量。 – Sergio

+0

@Serhio为什么他会使用条件变量,如果问题要求他使用信号量?他的伪代码没问题,只是C语言翻译错了。 –

+0

@PaoloBonzini互斥量经常被视为二进制信号量(只有两个计数器值:1或0),因此IMO翻译是相当合法的。因为互斥体不提供这种能力,所以需要条件变量来“解冻”等待线程。 – Sergio

回答

-1

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

1

A pthread_mutex_t不是信号量(虽然信号量可以用作互斥量,如果您执行“V”将其初始化为“free”)。信号量API是sem_init,sem_postsem_wait

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

+0

'sem _ *()'系列不是pthread API,它是为进程间通信而设计的。 – Sergio

+0

@Serhio函数[semaphore.h'中提供](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/semaphore.h.html)是为内部和*内部*进程通信而设计的,每[文档](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_init.html)。这里使用它们非常合适。 –

+0

@AndrewHenle哦,我的坏。谢谢! – Sergio

0

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

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