c - 生产者和消费者代码不出现在屏幕上

标签 c mutex semaphore

我有以下代码,但生产者和消费者代码没有出现。它只是打印“退出程序”。这就像消费者和生产者功能永远不会被执行。我不明白为什么会这样。谁能解释为什么? 代码如下:

/* buffer.h */
typedef int buffer_item;
#define BUFFER_SIZE 18

/* main.c */

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
/* #include "buffer.h" */


#define RAND_DIVISOR 100000000
#define TRUE 1

/* The mutex lock */
pthread_mutex_t mutex;

/* the semaphores */
sem_t full, empty;

/* the buffer */
buffer_item buffer[BUFFER_SIZE];

/* buffer counter */
int counter;

pthread_t tid;       //Thread ID
pthread_attr_t attr; //Set of thread attributes

void *producer(void *param); /* the producer thread */
void *consumer(void *param); /* the consumer thread */

void initializeData()
{

    /* Create the mutex lock */
    pthread_mutex_init(&mutex, NULL);

    /* Create the full semaphore and initialize to 0 */
    sem_init(&full, 0, 0);

    /* Create the empty semaphore and initialize to BUFFER_SIZE */
    sem_init(&empty, 0, BUFFER_SIZE);

    /* Get the default attributes */
    pthread_attr_init(&attr);

    /* init buffer */
    counter = 0;
}

/* Producer Thread */
void *producer(void *param)
{
    buffer_item item;

    while(TRUE)
    {
        /* sleep for a random period of time */
        int rNum = rand() / RAND_DIVISOR;
        sleep(rNum);

        /* generate a random number */
        item = rand();

        /* acquire the empty lock */
        sem_wait(&empty);
        /* acquire the mutex lock */
        pthread_mutex_lock(&mutex);

        if (insert_item(item))
            fprintf(stderr, " Producer report error condition\n");
        else
            printf("producer produced %d\n", item);

        /* release the mutex lock */
        pthread_mutex_unlock(&mutex);
        /* signal full */
        sem_post(&full);
    }
}

/* Consumer Thread */
void *consumer(void *param)
{
    buffer_item item;

    while(TRUE) {
        /* sleep for a random period of time */
        int rNum = rand() / RAND_DIVISOR;
        sleep(rNum);

        /* aquire the full lock */
        sem_wait(&full);
        /* aquire the mutex lock */
        pthread_mutex_lock(&mutex);
        if (remove_item(&item)) {
           fprintf(stderr, "Consumer report error condition\n");
        } else {
            printf("consumer consumed %d\n", item);
        }
        /* release the mutex lock */
        pthread_mutex_unlock(&mutex);
        /* signal empty */
        sem_post(&empty);
    }
}

/* Add an item to the buffer */
int insert_item(buffer_item item)
{
    /* When the buffer is not full add the item
      and increment the counter*/
    if (counter < BUFFER_SIZE) {
        buffer[counter] = item;
        counter++;
        return 0;
    } else { /* Error the buffer is full */
        return -1;
    }
}

/* Remove an item from the buffer */
int remove_item(buffer_item *item)
{
    /* When the buffer is not empty remove the item
      and decrement the counter */
    if (counter > 0) {
        *item = buffer[(counter-1)];
        counter--;
        return 0;
    } else { /* Error buffer empty */
        return -1;
    }
}

int main(int argc, char *argv[])
{
    /* Loop counter */
    int i;

     /* Verify the correct number of arguments were passed in */
    if(argc != 4) {
        fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
    }

    int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */
    int numProd = atoi(argv[2]); /* Number of producer threads */
    int numCons = atoi(argv[3]); /* Number of consumer threads */

    /* Initialize the app */
    initializeData();

    /* Create the producer threads */
    for(i = 0; i < numProd; i++) {
        /* Create the thread */
        pthread_create(&tid,&attr,producer,NULL);
    }

    /* Create the consumer threads */
    for(i = 0; i < numCons; i++) {
        /* Create the thread */
        pthread_create(&tid,&attr,consumer,NULL);
    }

    /* Sleep for the specified amount of time in milliseconds */
    sleep(mainSleepTime);

    /* Exit the program */
    printf("Exit the program\n");
    exit(0);
}

最佳答案

首先,您需要为线程应用不同的 tid。

pthread_t tid1, tid2;

然后使用这些 tid:

pthread_create(&tid1, &attr, producer, NULL);

pthread_create(&tid2, &attr, consumer, NULL);

最后,跳过 sleep 并加入线程。

pthread_join(tid1, NULL);

pthread_join(tid2, NULL);

我已经对其进行了测试,并且可以在我的系统上运行。以下是完整的工作代码。

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


#define RAND_DIVISOR 100000000
#define TRUE 1

/* The mutex lock */
pthread_mutex_t mutex;

/* the semaphores */
sem_t full, empty;

/* the buffer */
buffer_item buffer[BUFFER_SIZE];

/* buffer counter */
int counter;

pthread_t tid1, tid2;       //Thread ID
pthread_attr_t attr; //Set of thread attributes

void *producer(void *param); /* the producer thread */
void *consumer(void *param); /* the consumer thread */

void initializeData() {

   /* Create the mutex lock */
   pthread_mutex_init(&mutex, NULL);

   /* Create the full semaphore and initialize to 0 */
   sem_init(&full, 0, 0);

   /* Create the empty semaphore and initialize to BUFFER_SIZE */
   sem_init(&empty, 0, BUFFER_SIZE);

   /* Get the default attributes */
   pthread_attr_init(&attr);

   /* init buffer */
   counter = 0;
}

/* Producer Thread */
void *producer(void *param) {
   buffer_item item;

   while(TRUE) {
      /* sleep for a random period of time */
      int rNum = rand() / RAND_DIVISOR;
      sleep(rNum);

      /* generate a random number */
      item = rand();

      /* acquire the empty lock */
      sem_wait(&empty);
      /* acquire the mutex lock */
      pthread_mutex_lock(&mutex);

      if(insert_item(item)) {
         fprintf(stderr, " Producer report error condition\n");
      }
      else {
         printf("producer produced %d\n", item);
      }
      /* release the mutex lock */
      pthread_mutex_unlock(&mutex);
      /* signal full */
      sem_post(&full);
   }
}

/* Consumer Thread */
void *consumer(void *param) {
   buffer_item item;

   while(TRUE) {
      /* sleep for a random period of time */
      int rNum = rand() / RAND_DIVISOR;
      sleep(rNum);

      /* aquire the full lock */
      sem_wait(&full);
      /* aquire the mutex lock */
      pthread_mutex_lock(&mutex);
      if(remove_item(&item)) {
         fprintf(stderr, "Consumer report error condition\n");
      }
      else {
         printf("consumer consumed %d\n", item);
      }
      /* release the mutex lock */
      pthread_mutex_unlock(&mutex);
      /* signal empty */
      sem_post(&empty);
   }
}

/* Add an item to the buffer */
int insert_item(buffer_item item) {
   /* When the buffer is not full add the item
      and increment the counter*/
   if(counter < BUFFER_SIZE) {
      buffer[counter] = item;
      counter++;
      return 0;
   }
   else { /* Error the buffer is full */
      return -1;
   }
}

/* Remove an item from the buffer */
int remove_item(buffer_item *item) {
   /* When the buffer is not empty remove the item
      and decrement the counter */
   if(counter > 0) {
      *item = buffer[(counter-1)];
      counter--;
      return 0;
   }
   else { /* Error buffer empty */
      return -1;
   }
}

int main(int argc, char *argv[]) {
   /* Loop counter */
   int i;

   /* Verify the correct number of arguments were passed in */
   if(argc != 4) {
      fprintf(stderr, "USAGE:./main.out <INT> <INT> <INT>\n");
   }

   int mainSleepTime = atoi(argv[1]); /* Time in seconds for main to sleep */
   int numProd = atoi(argv[2]); /* Number of producer threads */
   int numCons = atoi(argv[3]); /* Number of consumer threads */

   /* Initialize the app */
   initializeData();

   /* Create the producer threads */
   for(i = 0; i < numProd; i++) {
      /* Create the thread */
      pthread_create(&tid1,&attr,producer,NULL);
    }

   /* Create the consumer threads */
   for(i = 0; i < numCons; i++) {
      /* Create the thread */
      pthread_create(&tid2,&attr,consumer,NULL);
   }

   /* Sleep for the specified amount of time in milliseconds */
   //sleep(mainSleepTime);

   pthread_join(tid1, NULL);
   pthread_join(tid2, NULL);

   /* Exit the program */
   printf("Exit the program\n");
   exit(0);
}

关于c - 生产者和消费者代码不出现在屏幕上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14171230/

相关文章:

linux - 用于 Linux 的混合互斥库

c# - 避免运行多个实例

c++ - 我可以只用事件、互斥量和信号量实现公平的 "wait on multiple events"吗?

c - 并行 (CUDA) 二维泊松求解器

无法实现带有可变参数的函数

c - 一个简单的 x86 反汇编器开源内核使用

c - 错误行 : 43 compiler: expected identifier or '(' before ' [ ' token

c - 如何控制互斥量的加锁和解锁?

c - 不同.c文件之间的IPC进程间通信

c - 4 使用信号量进行4路同步(在C编程、UNIX环境中)