生产者/消费者程序出现未知错误,相信是无限循环

发布于 2024-08-29 06:59:18 字数 3550 浏览 3 评论 0原文

我正在编写一个程序来解决生产者/消费者问题,特别是有界缓冲区版本(我相信它们的意思是相同的)。生产者将生成 x 个随机数,其中 x 是我的程序的命令行参数。目前,我相信我的程序正在进入无限循环,但我不确定为什么会发生。我相信我正确执行了信号量。

你像这样编译它: gcc -o prodcon prodcon.cpp -lpthread -lrt 然后运行,./prodcon 100(要生成的随机数)

这是我的代码。

 typedef int buffer_item;

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

 #define BUFF_SIZE 10
 #define RAND_DIVISOR 100000000
 #define TRUE 1

 //two threads
 void *Producer(void *param);  
 void *Consumer(void *param);

 int insert_item(buffer_item item);
 int remove_item(buffer_item *item);
 int returnRandom();


 //the global semaphores

 sem_t empty, full, mutex;

 //the buffer

 buffer_item buf[BUFF_SIZE];

 //buffer counter
 int counter;

 //number of random numbers to produce
 int numRand;

 int main(int argc, char** argv) {
 /* thread ids and attributes */
 pthread_t pid, cid;  
 pthread_attr_t attr;
 pthread_attr_init(&attr);
 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

 numRand = atoi(argv[1]);
 sem_init(&empty,0,BUFF_SIZE);
 sem_init(&full,0,0);
 sem_init(&mutex,0,0);

 printf("main started\n");
 pthread_create(&pid, &attr, Producer, NULL);
 pthread_create(&cid, &attr, Consumer, NULL);
 printf("main gets here");
 pthread_join(pid, NULL);
 pthread_join(cid, NULL);
 printf("main done\n");

 return 0;

 }

 //generates a randum number between 1 and 100
 int returnRandom()
 {
  int num;
  srand(time(NULL));
  num = rand() % 100 + 1;
  return num;
 }

 //begin producing items
 void *Producer(void *param) {
    buffer_item item;
    int i;
    for(i = 0; i < numRand; i++)
    {
     //sleep for a random period of time
     int rNum = rand() / RAND_DIVISOR;
     sleep(rNum);

     //generate a random number
     item = returnRandom();

     //acquire the empty lock
     sem_wait(&empty);

     //acquire the mutex lock
     sem_wait(&mutex);

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

 /* Consumer Thread */
 void *Consumer(void *param) {
    buffer_item item;
    int i;
    for(i = 0; i < numRand; i++) {
    /* 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 */
    sem_wait(&mutex);
    if(remove_item(&item)) {
    fprintf(stderr, "Consumer report error condition\n");
    }
    else {
    printf("consumer consumed %d\n", item);
    }
    /* release the mutex lock */
    sem_post(&mutex);
    /* signal empty */
    sem_post(&empty);
    }
    return NULL;
 }

  /* 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 < BUFF_SIZE) {
    buf[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 = buf[(counter-1)];
    counter--;
    return 0;
    }
    else { /* Error buffer empty */
    return -1;
    }
 }

I am writing a program that is solving the producer/consumer problem, specifically the bounded-buffer version(i believe they mean the same thing). The producer will be generating x number of random numbers, where x is a command line parameter to my program. At the current moment, I believe my program is entering an infinite loop, but I'm not sure why it is occurring. I believe I am executing the semaphores correctly.

You compile it like this:
gcc -o prodcon prodcon.cpp -lpthread -lrt
Then to run, ./prodcon 100(the number of randum nums to produce)

This is my code.

 typedef int buffer_item;

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

 #define BUFF_SIZE 10
 #define RAND_DIVISOR 100000000
 #define TRUE 1

 //two threads
 void *Producer(void *param);  
 void *Consumer(void *param);

 int insert_item(buffer_item item);
 int remove_item(buffer_item *item);
 int returnRandom();


 //the global semaphores

 sem_t empty, full, mutex;

 //the buffer

 buffer_item buf[BUFF_SIZE];

 //buffer counter
 int counter;

 //number of random numbers to produce
 int numRand;

 int main(int argc, char** argv) {
 /* thread ids and attributes */
 pthread_t pid, cid;  
 pthread_attr_t attr;
 pthread_attr_init(&attr);
 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

 numRand = atoi(argv[1]);
 sem_init(&empty,0,BUFF_SIZE);
 sem_init(&full,0,0);
 sem_init(&mutex,0,0);

 printf("main started\n");
 pthread_create(&pid, &attr, Producer, NULL);
 pthread_create(&cid, &attr, Consumer, NULL);
 printf("main gets here");
 pthread_join(pid, NULL);
 pthread_join(cid, NULL);
 printf("main done\n");

 return 0;

 }

 //generates a randum number between 1 and 100
 int returnRandom()
 {
  int num;
  srand(time(NULL));
  num = rand() % 100 + 1;
  return num;
 }

 //begin producing items
 void *Producer(void *param) {
    buffer_item item;
    int i;
    for(i = 0; i < numRand; i++)
    {
     //sleep for a random period of time
     int rNum = rand() / RAND_DIVISOR;
     sleep(rNum);

     //generate a random number
     item = returnRandom();

     //acquire the empty lock
     sem_wait(&empty);

     //acquire the mutex lock
     sem_wait(&mutex);

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

 /* Consumer Thread */
 void *Consumer(void *param) {
    buffer_item item;
    int i;
    for(i = 0; i < numRand; i++) {
    /* 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 */
    sem_wait(&mutex);
    if(remove_item(&item)) {
    fprintf(stderr, "Consumer report error condition\n");
    }
    else {
    printf("consumer consumed %d\n", item);
    }
    /* release the mutex lock */
    sem_post(&mutex);
    /* signal empty */
    sem_post(&empty);
    }
    return NULL;
 }

  /* 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 < BUFF_SIZE) {
    buf[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 = buf[(counter-1)];
    counter--;
    return 0;
    }
    else { /* Error buffer empty */
    return -1;
    }
 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅笑依然 2024-09-05 06:59:18
 sem_init(&empty,0,BUFF_SIZE);
 sem_init(&full,0,0);

也尝试在这里初始化“互斥”信号量。

 sem_init(&empty,0,BUFF_SIZE);
 sem_init(&full,0,0);

Try initializing the "mutex" semaphore here as well.

葬シ愛 2024-09-05 06:59:18

将互斥锁初始化为 1。
尝试注释掉睡眠调用(我没有解释,除了“它对我有用”)。
编辑:睡眠需要几秒钟,它可能看起来被阻止,因为随机数太高。

在你的 main 中调用 srand (否则你会得到相同的值,因为你在同一时间再次播种)。

Initialise the mutex to 1.
Try commenting out the calls to sleep (i don't have an explanation, except "it works for me").
Edit : sleep takes a number of seconds, it may look blocked because the random number is too high.

Call srand in your main (otherwise you'll get identical values, as you seed again with the same time).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文