【问题标题】:Thread syncronization to print 5 random numbers线程同步打印5个随机数
【发布时间】:2011-12-17 16:18:40
【问题描述】:

我被要求编写一个有 2 个线程并打印 5 个随机整数的程序,这样第一个线程将生成一个数字,第二个线程将打印它。然后第一个线程将生成第二个数字,第二个线程将打印它......等等。使用互斥锁。

我的代码现在执行一个周期。如何扩展它以使线程执行方法 5 次?

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

void* generate (void*);
void* print (void*);

pthread_mutex_t m;
int number = 5;
int genNumber;


int main()
{
    int i;
    srandom(getpid());
    pthread_t th[2];

    pthread_mutex_init(&m,NULL);

    pthread_create(&th[0],NULL,generate,NULL);
    pthread_create(&th[1],NULL,print, NULL);

    for (i = 0; i < 2; i++)
        pthread_join(th[i], NULL);

    pthread_mutex_destroy(&m);

    return 0;
}

void* generate(void* arg)
{
    pthread_mutex_lock(&m);
    genNumber = random() % 9;
    printf("Generated #1 \n");
    pthread_mutex_unlock(&m);
}

void* print(void* arg)
{
    pthread_mutex_lock(&m);
    printf("The number is %d " , genNumber);
    pthread_mutex_unlock(&m);
    pthread_exit(NULL);
}

【问题讨论】:

  • 你为什么要为此使用多线程...?这是家庭作业的要求吗?
  • 是的。作为互斥体和信号量的一种实践

标签: c++ c pthreads


【解决方案1】:

使用condition variables 同步两个线程。当一个线程完成它的工作时,它会通知另一个线程唤醒,然后它进入睡眠状态等待更多的工作。所以是这样的:

// Pseudocode
pthread_cond_t c1, c2;
pthread_mutex_t mutex;

// Thread 1 (producer):
for(int i = 0; i < 5; i++)
{
    lock(mutex);
    genNumber = random() % 9;
    signal(c2);
    wait(c1, mutex);
    unlock(mutex);
}

// Thread 2 (consumer):
for(int i = 0; i < 5; i++)
{
    lock(mutex);
    wait(c2, mutex);
    print("The number is %d\n", genNumber);
    signal(c1);
    unlock(mutex);
}

【讨论】:

  • 生产者不应该在wait(c1,mutex)之前先解锁(mutex),消费者在lock(mutex)之前先wait(c2,mutex)吗?
【解决方案2】:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
static int *generate(void *);
static int *print(void *);
pthread_mutex_t m; 
pthread_cond_t con;
int munmber=10;
int gennumber;

int main() {
    srandom(getpid());
    pthread_t th1,th2;
    pthread_mutex_init(&m,NULL);
    pthread_create(&th2,NULL,print,NULL);
    sleep(1);
    pthread_create(&th1,NULL,generate,NULL);
    pthread_join(th1,NULL);
    pthread_join(th2,NULL);
    pthread_mutex_destroy(&m);

   }

  static int *generate(void *arg) {
  int i;
    while(i<5) {
            pthread_mutex_lock(&m);
            gennumber=random()%8;
            printf("NUMMBER GENERATED.... \n");
            pthread_cond_signal(&cond);
            i++;
            pthread_mutex_unlock(&m);
            sleep(2);
            if(i==5)
              exit(1);
    }

    return 0;
   }
    static int *print(void *arg) {
    int i;
    while('a') {
            pthread_cond_wait(&cond,&m);
            printf("GENERATED NUMBER is %d\n",gennumber);
            i++;
            pthread_mutex_unlock(&m);


    }

    return 0;
 }

【讨论】:

    【解决方案3】:

    在这里,互斥锁是不够的。您将需要一个条件变量来确保以正确的顺序打印数字。一些伪代码:

    //producer thread:
    for(int i = 0; i < 5; i++)
    {
        number = random();
        signal the other thread with pthread_cond_signal
        wait for signal from the consumer
    }
    
    // consumer thread
    for(int i = 0; i < 5; i++)
    {
        wait for signal with pthread_cond_wait
        print number
        signal the producer to produce another number
    }
    

    【讨论】:

    • 嗯,你可以用一个互斥锁和轮询来做到这一点,所以关于“不够”并不是真的。但显然其他方面更好
    【解决方案4】:

    你可以这样做:

    int* generated = null;
    
    void generate() {
      int i = 0;
      while (i<5) {
        pthread_mutex_lock(&m);
        if (generated == null) {
          generated = malloc(int);
          *generated = random() % 9;
          printf("Generated #1 \n");
          ++i;
        }
        pthread_mutex_unlock(&m);
      }
      pthread_exit(NULL);
    }
    
    void print() {
      int i = 0;
      while (i<5) {
        pthread_mutex_lock(&m);
        if (generated != null) {
          printf("The number is %d " , generated);
          free(generated);
          generated=null;
        }
        pthread_mutex_unlock(&m);
      }
      pthread_exit(NULL);
    }
    

    实际上我确实在没有编译器的情况下编写了它,因此可能会出现一些错误,但这个概念应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 2015-11-24
      • 1970-01-01
      • 2014-04-11
      相关资源
      最近更新 更多