2017-05-24 24 views
2

3猴子,每个猴子都会打印它的值。 Monkey1()打印1,依此类推。第一只猴子是最强的,他打印两次1,然后monkey2打印2,然后再次monkey1打印,然后monkey2,然后monkey3可以打印他的价值。3只猴子的打印值必须与信号同步

预期输出: 1 1 2 1 1 2 3 1 1 2 1 1 2 3 1 1 2等..

我只允许使用2信号量,每只猴子是一个线程。

嗯,我一直在想它一个多小时,我仍然不知道如何实现这一点。我很乐意就如何解决这个问题获得一些指导。

下面的代码的样子,这将帮助是什么系统/语言我使用的,代码不是在诅咒的时刻工作..

#include <time.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <string.h> 
#include <pthread.h> 
#include <semaphore.h> 

//3 monkeys so N = 3 
#define N 3 

sem_t s1,s2; 

void* Monkey1(void* param) 
{ 
    int i; 

    for(i = 0; i < 2; i++){ 
     printf("1"); 
     sem_wait(&s1); 
    } 

} 
void* Monkey2() 
{ 
    int i; 
    for(i = 0; i < 2; i++){ 
     sem_post(&s1); 
    } 
    printf("2"); 
    sem_wait(&s2); 
} 
void* Monkey3() 
{ 
    printf("3"); 
    //sem_wait(&s1); 
} 


void main() 
{ 
    pthread_t thread[N]; 
    int i, ans[N]; 

    sem_init(&s1, 0, 1); 
    sem_init(&s2,0,0); 

    for(i=0;i<N;i++) 
    { 
     ans[i] = i + 1; 
    } 

    if (pthread_create (&thread[0] , NULL , Monkey1 , (void*)&ans[0]) != 0) 
    { 
     perror("Could not create thread"); 
     exit(1); 
    } 


    if (pthread_create (&thread[1] , NULL , Monkey2 , (void*)&ans[1]) != 0) 
    { 
     perror("Could not create thread"); 
     exit(1); 
    } 

    if (pthread_create (&thread[2] , NULL , Monkey3 , (void*)&ans[2]) != 0) 
    { 
     perror("Could not create thread"); 
     exit(1); 
    } 


    for(i=0;i<N;i++) 
    { 
     pthread_join(thread[i], NULL); 
    } 


} 

回答

1

这是它是如何实现的(我已经包含注释来解释它是如何工作的,不是这两个sempaphores与值1初始化,有一些sleep(1)调用使线程在屏幕上隔行可见) :

#define N 3 

sem_t s1, s2; 

void *Monkey1(void *param) { 
    while (1) { 
    sleep(1); 
    for (int j = 0; j < 2; j++) { 
     sleep(1); 
     sem_wait(&s1); 
     for (int i = 0; i < 2; i++) { 
     printf("1\n"); 
     } 
     sem_post(&s1); 
    } 
    } 
} 
void *Monkey2() { 
    while (1) { 
    sleep(1); 
    sem_wait(&s2); // Wait for monkey 3 
    for (int i = 0; i < 2; ++i) { 
     sleep(1); 
     sem_wait(&s1); // Wait for monkey 1 
     printf("2\n"); 
     sem_post(&s1); 
    } 
    sem_post(&s2); 
    } 
} 
void *Monkey3() { 
    while (1) { 
    sleep(1); 
    sem_wait(&s2); // Wait for monkey 2 
    sleep(1); 
    sem_wait(&s1); // Wait for monkey 1 
    printf("3\n"); 
    sem_post(&s2); 
    sem_post(&s1); 
    } 
} 
int main() { 
    pthread_t thread[N]; 
    int i, ans[N]; 

    sem_init(&s1, 0, 1); 
    sem_init(&s2, 0, 1); 

    for (i = 0; i < N; i++) { 
    ans[i] = i + 1; 
    } 

    if (pthread_create(&thread[0], NULL, Monkey1, NULL) != 0) { 
    perror("Could not create thread"); 
    exit(1); 
    } 

    if (pthread_create(&thread[1], NULL, Monkey2, NULL) != 0) { 
    perror("Could not create thread"); 
    exit(1); 
    } 

    if (pthread_create(&thread[2], NULL, Monkey3, (void *)&ans[2]) != 0) { 
    perror("Could not create thread"); 
    exit(1); 
    } 

    for (i = 0; i < N; i++) { 
    pthread_join(thread[i], NULL); 
    } 
    return 0; 
} 
+0

它几乎可以工作,它打印211211231121123 ..第2个被删除。你知道如何解决这个问题吗? ? –

+0

另外,我不知道如何去关注它。:( –

+1

猴子2可能会也可能不会启动 - 这取决于线程加入的顺序(它可以通过互斥锁来修复)。重新,它的作用和你的例子完全一样。 – syntagma

1

你可以改变一点点了Monkey1,2,3功能如下:

void* Monkey1(void* param) 
{ 
    int i; 
    //it starts to print first, two times number 1 and triggers Monkey 2 
    for(i = 0; i < 2; i++){ 
     printf("1"); 
    } 
    sem_post(&s1);//start Monkey2 
    sem_wait(&s2); 
    for(i = 0; i < 2; i++){ 
     printf("1"); 
    } 
sem_post(&s1); //start Monkey2 and Monkey3 but Monkey3 waits also sem2 
sem_post(&s1); 
} 
void* Monkey2() 
{ 
    int i; 
    sem_wait(&s1); //doesn't start until Monkey 1 allows 
    printf("2"); 
    sem_post(&s2); 
    sem_post(&s2); //allow both Monkey1 and Monkey2 but Monkey2 needs also s1 sem 
    sem_wait(&s1); //wait Monkey 1 
    printf("2"); 
    sem_post(&s2); 
} 
void* Monkey3() 
{ 
    sem_wait(&s2); 
    sem_wait(&s1); 
    sem_wait(&s2); 
    printf("3"); 

} 
+0

嗯,它不工作。我将sem初始化为0,0和112112 –

+0

我在1分钟前编辑了答案,并且在Monkey1的末尾增加了一个'sem_post(&s1);'''''''''''''''''' s1,s2初始化为0 .... – coder

+0

仍然一样,没有工作.. –

0

这是一个有点棘手,以得到它的权利。猴子1只能使用信号1被猴子2唤醒,而猴子3只能使用信号2被猴子2唤醒。这将保证打印顺序。重复一遍,简单地在里面放一段时间循环。

void* Monkey1(void* param) 
{ 
    int i; 
    //it starts to print first, two times number 1 and triggers Monkey 2 
    for(i = 0; i < 2; i++){ 
     printf("1"); 
    } 
    sem_post(&s1);//start Monkey2 
    sem_wait(&s1); 
    for(i = 0; i < 2; i++){ 
    printf("1"); 
    } 
    sem_post(&s1); 
    sem_wait(&s1); 
} 

void* Monkey2() 
{ 
    sem_wait(&s1); //doesn't start until Monkey 1 allows 
    printf("2"); 
    sem_post(&s1); 
    sem_wait(&s1); 
    printf("2"); 
    sem_post(&s2); 
    sem_wait(&s2); 
    sem_post(&s1); 
} 

void* Monkey3() 
{ 
    sem_wait(&s2); 
    printf("3"); 
    sem_post(&s2); 
} 
+0

这不起作用。假设sem的初始值是0,0 –

+0

如果它是1,0像在后,然后它打印22111 –

+0

@Ilan Aizelman WS你是否试图运行它?我的输出是1121123,并且两个信号都应该初始化为0 – codeinc