c - 使用条件变量进行线程间通信?

标签 c multithreading pthreads

假设我在一个进程中有三个线程th1、th2和th3以及三个寄存器(数组)a、b和c。 th1 和 th2 仅写入三个寄存器之一,th3 仅从这些寄存器读取数据。 th1、th2 和 th3 将按照等待条件变量的连续顺序 b/c 工作。两个条件变量cv1和cv2分别用于(th1,th2)和(th2,th3)之间的信号传输。工作流程如下:

  1. 首先 th1 将一些内容写入“a”数组,然后向正在等待它的 th2 发出信号(使用 cv1)。
  2. 收到来自 th1 的信号后,th2 开始写入同一个数组“a”,然后向 th3 发送信号(使用 cv2)读取“a”。
  3. th3 在收到来自 th2 的信号后开始读取“a”(同一数组)。
  4. 以相同方式对“b”和“c”重复上述 3 个步骤。

我的c代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>

void* th1();
void* th2();
void* th3();

int a[40], b[40], c[40], rn;

pthread_mutex_t mutex1, mutex2, mutex3;
pthread_cond_t cv1, cv2;

int main()
{
    pthread_t  t[3];
    pthread_mutex_init(&mutex1, NULL);
    pthread_mutex_init(&mutex2, NULL);
    pthread_mutex_init(&mutex3, NULL);

    pthread_cond_init(&cv1, NULL);
    pthread_cond_init(&cv2, NULL);

    pthread_create(&t[0], NULL, th1, NULL);
    pthread_create(&t[1], NULL, th2, NULL);
    pthread_create(&t[2], NULL, th3, NULL);


    pthread_join(t[0], NULL);
    pthread_join(t[1], NULL);
    pthread_join(t[2], NULL);

    pthread_mutex_destroy(&mutex1);
    pthread_mutex_destroy(&mutex2);
    pthread_mutex_destroy(&mutex3);
    pthread_cond_destroy(&cv1);
    pthread_cond_destroy(&cv2);
    return 0;
}

void* th1()
{       
    pthread_mutex_lock(&mutex1);
        for(int i=0; i<20; i++)
        {
            a[i]=i;
            }
        pthread_cond_signal(&cv1);
        puts("a signal sent...");
    pthread_mutex_unlock(&mutex1);


    pthread_mutex_lock(&mutex2);
        for(int i=0; i<20; i++)
        {
            b[i]=i;
            }
        pthread_cond_signal(&cv1);
        puts("b signal sent...");
    pthread_mutex_unlock(&mutex2);


    pthread_mutex_lock(&mutex3);
        for(int i=0; i<20; i++)
        {
            c[i]=i;
            }
        pthread_cond_signal(&cv1);
        puts("c signal sent...");
    pthread_mutex_unlock(&mutex3);

    pthread_exit(NULL);
}

void* th2()
{
    pthread_mutex_lock(&mutex1);
        pthread_cond_wait(&cv1, &mutex1);
        puts("signal recv form th1 for writing 'a'...\n");
        for(int i=0; i<=20; i++)
        {
            a[i+20]=i+20;
        }
        pthread_cond_signal(&cv2);
    pthread_mutex_unlock(&mutex1);


    pthread_mutex_lock(&mutex2);
        pthread_cond_wait(&cv1, &mutex2);
        puts("signal recv from th1 for writing 'b'...\n");
        for(int i=0; i<=20; i++)
        {
            b[i+20]=i+20;
        }
        pthread_cond_signal(&cv2);
    pthread_mutex_unlock(&mutex2);


    pthread_mutex_lock(&mutex3);
        pthread_cond_wait(&cv1, &mutex3);
        puts("signal recv from th1 for writing 'c'...\n");
        for(int i=0; i<=20; i++)
        {
            c[i+20]=i+20;
        }
        pthread_cond_signal(&cv2);
    pthread_mutex_unlock(&mutex3);

    pthread_exit(NULL);
}
void* th3()
{

    pthread_mutex_lock(&mutex1);
        pthread_cond_wait(&cv2, &mutex1);
        puts(" signal recv from th2 for reading 'a'...\n");
        for(int i=0; i<=40; i++)
        {
            printf("%d   :",a[i]);
        }
        printf("\n\n");
    pthread_mutex_unlock(&mutex1);


    pthread_mutex_lock(&mutex2);
        pthread_cond_wait(&cv2, &mutex2);
        puts(" signal recv from th2 for reading 'b'...\n");
        for(int i=0; i<=40; i++)
        {
            printf("%d   :",b[i]);
        }
        printf("\n\n");
    pthread_mutex_unlock(&mutex2);


    pthread_mutex_lock(&mutex3);
        pthread_cond_wait(&cv2, &mutex3);
        puts(" signal recv from th2 for reading 'c'...\n");
        for(int i=0; i<=40; i++)
        {
            printf("%d   :",c[i]);
        }
        printf("\n\n");
    pthread_mutex_unlock(&mutex3);

    pthread_exit(NULL);

}

显示后输出 block :

mohtashim-ul-haq@mohtashim-pc:~/Documents/rough$ gcc tread.c -o tread -lpthread
mohtashim-ul-haq@mohtashim-pc:~/Documents/rough$ ./tread
a signal sent...
b signal sent...
c signal sent...

我的预期输出是这样的:

    a signal sent
    signal recv form th1 for writing 'a'...
    signal recv from th2 for reading 'a'...
    1 2 3 4 ..... 40

    b signal sent
    signal recv form th1 for writing 'b'...
    signal recv from th2 for reading 'b'...
    1 2 3 4 ..... 40

    c signal sent
    signal recv form th1 for writing 'c'...
    signal recv from th2 for reading 'c'...
    1 2 3 4 ..... 40

我想,我无法理解条件变量如何与互斥体结合使用。有什么帮助吗???

最佳答案

您需要集成事件“信号”,会说您需要存储是否引发了信号(通知状态更改)。

对于第一个事件(“a”读取),对代码的调整可能如下所示:

int a_read = 0; /* to store the event "a had been read" actually happened */

void* th1(void * pvunused)
{       
    pthread_mutex_lock(&mutex1);
    for(int i=0; i<20; i++)
    {
        a[i]=i;
    }

    a_read = 1;
    pthread_cond_signal(&cv1);
    ...


void* th2(void * pvunused)
{
  pthread_mutex_lock(&mutex1);
  while (0 == a_read) /* Theoretical an "if" would do here, 
                         using "while" lets you stay on the safe side, in case
                         a "spurious wake-up" (https://en.wikipedia.org/wiki/Spurious_wakeup)
                         occurred. */
  {
    pthread_cond_wait(&cv1, &mutex1);
  }

  ...

关于c - 使用条件变量进行线程间通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44772001/

相关文章:

c - 高效查找和替换 gzip 内容上的数据

ios - Async_Dispatch 线程

c# - 如何在 C# .net 中每天早上执行一个方法

c++ - 在 C++ 中等待分离的线程完成

c++ - C语言中有字符串吗?

c - 如何以缓存友好的方式访问灵活数组的数组?

Java extendsThread vs Implements runnable 来模拟权限

php - 在php中使用pthread进行Multiupload

c++ - C++ 中的 Pthread 用法

C-运行程序接受输入