C 对如何初始化和实现 pthread 互斥体和条件变量感到困惑

标签 c pthreads conditional-statements mutex producer-consumer

我对如何初始化和实现 pthread 互斥锁和条件变量有点困惑。该程序的目标是让生产者在队列中放置一定数量的整数,而消费者将整数从队列中取出。我还必须能够定义创建的生产者和消费者线程的数量。在入门代码中,我给出了这些:

// Locks & Condition Variables
pthread_mutex_t lock; // Lock shared resources among theads
pthread_cond_t full;  // Condition indicating queue is full
pthread_cond_t empty; // Condition indicating queue is empty

作为共享资源。在 //TODO在 main 方法中添加注释,其中一个步骤是初始化锁和条件变量。我对 pthread 互斥体和条件的理解非常薄弱,所以我会说:
lock = PTHREAD_MUTEX_INIT;
full = PTHREAD_MUTEX_INIT;
empty = PTHREAD_MUTEX_INIT;

在消费者和生产者方法中,我会通过说来调用锁:
pthread_mutex_lock(&lock);


pthread_cond_wait(&full, &lock);

?

我的代码现在有很多问题,所以我想至少在进一步调试之前确保我正确使用了互斥锁和条件。提前致谢!

最佳答案

如果您想使用 PTHREAD_XXX_INITIALIZER宏,您应该在变量声明中使用它们。也可以使用 PTHREAD_COND_INITIALIZER对于条件变量:

// Locks & Condition Variables
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // Lock shared resources among theads
pthread_cond_t full  = PTHREAD_COND_INITIALIZER;  // Condition indicating queue is full
pthread_cond_t empty = PTHREAD_COND_INITIALIZER; // Condition indicating queue is empty
以后不要使用这些宏来初始化互斥锁或条件变量。如果您需要稍后执行(例如,如果对象是动态分配的),请使用适当的 init 函数:
pthread_mutex_init( &lock, NULL);
pthread_cond_init( &full, NULL);
pthread_cond_init( &empty, NULL);
要检查条件变量,您必须使用循环以避免虚假解除阻塞,并且您必须在以下情况下锁定互斥锁:
  • 检查条件
  • 更改指示当前条件的状态
  • 调用 pthread_cond_wait()

  • 因此,等待空状态的任何内容可能如下所示:
    pthread_mutex_lock(&lock);
    while (!isEmpty) {
        pthread_cond_wait(&empty, &lock);
    }
    
    // isEmpty is non-zero and the lock is held
    
    无论是什么信号表明某物是空的,可能看起来像:
    pthread_mutex_lock(&lock);
    
    // ...
    // we have emptied the queue while holding the lock
    
    isEmpty = 1;
    pthread_mutex_unlock(&lock);
    pthread_cond_signal(&empty);
    

    关于C 对如何初始化和实现 pthread 互斥体和条件变量感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23400097/

    相关文章:

    c - 为什么 malloc() 和 printf() 被称为不可重入?

    c - 为什么 main() 不能在 C 中声明为静态的?

    c - 段错误(核心转储)pthread

    c++ - linux CFS schedualar下C/C++多线程场景出现意外结果

    javascript - 在javascript中如何从数量字符串中添加或删除 's'

    c - swift 等同于 C 中的头文件?

    c - 反向保存字符串

    linux - Linux 中每个进程的最大线程数

    Java 控制台程序不让我输入字符串

    xslt - != XPath 运算符的奇怪行为