代码之家  ›  专栏  ›  技术社区  ›  Jay Wang

生产者/消费者实施:陷入消费者循环

  •  0
  • Jay Wang  · 技术社区  · 6 年前

    我正在尝试使用实现生产者/消费者问题 pthread 在C中,我有一个全局变量 int num_available 作为我的两个条件变量的状态变量 fill empty

    这是我的生产者代码,它应该填补工作岗位并向消费者发出信号。

    void *producer(void *arg){
        // Parse the arguments
        struct producer_arg_struct *real_arg = (struct producer_arg_struct*) arg;
        char *data = real_arg -> data;
        size_t filesize = real_arg -> filesize;
    
        // Start the producer loop
        while(cur_chunk < data + filesize){
            pthread_mutex_lock(&mutex);
            printf("producer got lock, items: %d\n", num_available);
    
            // Wait for consumers
            while(num_available == MAX){
                printf("producer: sleep\n");
                pthread_cond_wait(&empty, &mutex);
            }
    
            // At least one work to fill
            cur_chunk += CHUNK_SIZE;
            cur_result++;
            num_available++;
    
            pthread_cond_signal(&fill);
            pthread_mutex_unlock(&mutex);
        }
        return NULL;
    }
    

    这是我的消费者代码,它应该完成工作并向消费者发出信号。

    void *consumer(void *arg){
        while(1){
            pthread_mutex_lock(&mutex);
            printf("consumer: got lock, item: %d\n", num_available);
            while(num_available == 0){
                // No works available
                printf("consumer: sleep\n");
                pthread_cond_wait(&fill, &mutex);
            }
    
            // Having at least one work available, do the work
            num_available--;
            compress(cur_chunk, cur_result);
    
            // Signal producer
            pthread_cond_signal(&empty);
            pthread_mutex_unlock(&mutex);
        }
        return NULL;
    }
    

    我的程序将陷入无限循环。有两种输出情况:

    1. 生产者首先获得锁:

      producer got lock, items: 0
      consumer: got lock, item: 1
      consumer: got lock, item: 0
      consumer: sleep
      consumer: sleep
      consumer: sleep
      ...
      
    2. 消费者首先获得锁:

      consumer: got lock, item: 0
      consumer: sleep
      consumer: sleep
      consumer: sleep
      ...
      

    看起来 pthread_cond_wait(&fill, &mutex) 请来 consumer() 不会真正释放锁或让消费者入睡。相反,它被困在无限循环中。

    我应该如何修复它?如有任何建议,将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Junhee Shin    6 年前

    我希望这能帮助你。 生产者和消费者线程问题。

    #include <stdio.h>
    #include <pthread.h>
    
    #define MAX 10000000000                 
    //#define MAX 10
    pthread_mutex_t the_mutex;
    pthread_cond_t condc, condp;
    int maxbuf=5 ;   // max produce count.
    int buffer = 0;
    
    void* producer(void *ptr) {
      int i;
    
      for (i = 1; i <= MAX; i++) {
        pthread_mutex_lock(&the_mutex);     /* protect buffer */
            printf("produce:get lock\n") ;
    
            if(buffer==maxbuf) {
              printf("produce:wait! maxbuffer.\n") ;
          pthread_cond_wait(&condp, &the_mutex);
              printf("produce:wake--\n") ;
            }
        buffer++;
            printf("produce: buffer=%d\n", buffer) ;
        pthread_cond_signal(&condc);        /* wake up consumer */
        pthread_mutex_unlock(&the_mutex);  
            usleep(rand()%100);
      }
      pthread_exit(0);
    }
    void* consumer(void *ptr) {
      int i;
      for (i = 1; i <= MAX; i++) {
        pthread_mutex_lock(&the_mutex);    
            printf("consume:get lock\n") ;
        if (buffer == 0)     /* If there is nothing in the buffer then wait */
            {
                    printf("consume: wait! empty.\n") ;
          pthread_cond_wait(&condc, &the_mutex);
              printf("consume: wake--.\n") ;
            }
        buffer--;
            printf("consume: buffer=%d\n", buffer) ;
        pthread_cond_signal(&condp);        /* wake up producer */
        pthread_mutex_unlock(&the_mutex);  
            usleep(rand()%100);
      }
      pthread_exit(0);
    }
    int main(int argc, char **argv) {
      pthread_t pro, con;
      // Initialize the mutex and condition variables
      /* What's the NULL for ??? */
      pthread_mutex_init(&the_mutex, NULL);
      pthread_cond_init(&condc, NULL);              /* Initialize consumer condition variable */
      pthread_cond_init(&condp, NULL);              /* Initialize producer condition variable */
      // Create the threads
      pthread_create(&con, NULL, consumer, NULL);
      pthread_create(&pro, NULL, producer, NULL);
      // Wait for the threads to finish
      // Otherwise main might run to the end
      // and kill the entire process when it exits.
      pthread_join(con, NULL);
      pthread_join(pro, NULL);
      // Cleanup -- would happen automatically at end of program
      pthread_mutex_destroy(&the_mutex);    /* Free up the_mutex */
      pthread_cond_destroy(&condc);         /* Free up consumer condition variable */
      pthread_cond_destroy(&condp);         /* Free up producer condition variable */
    }
    

    输出如下。。。 双螺纹座圈。

    consume:get lock
    consume: buffer=2
    produce:get lock
    produce: buffer=3
    produce:get lock
    produce: buffer=4
    consume:get lock
    consume: buffer=3
    consume:get lock
    consume: buffer=2
    produce:get lock
    

    如果为空

    produce:get lock
    produce: buffer=1
    consume:get lock
    consume: buffer=0
    consume:get lock
    consume: wait! empty.
    produce:get lock
    produce: buffer=1
    consume: wake--.
    consume: buffer=0
    produce:get lock
    produce: buffer=1
    consume:get lock
    

    如果最大产量。

    produce:get lock
    produce: buffer=5
    consume:get lock
    consume: buffer=4
    produce:get lock
    produce: buffer=5
    produce:get lock
    produce:wait! maxbuffer.
    consume:get lock
    consume: buffer=4
    produce:wake--
    produce: buffer=5
    produce:get lock