【问题标题】:C thread parallel programmingC线程并行编程
【发布时间】:2021-12-17 20:18:36
【问题描述】:

我尝试制作一个并行程序,用一个线程生成一个随机数,另一个线程编写它。

我做错了什么会影响性能/优化吗?我问它是因为编写这个程序很容易,所以我有点担心我做错了什么。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include "produceConsume.h"
#define NUM_THREAD 1

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int queue[1];
int queueCounter = 0;

void *producer(void *args)
{
    while (1)
    {
        pthread_mutex_lock(&lock);
        int n = rand() % 100;
        queue[queueCounter] = n;
        queueCounter++;
        pthread_cond_wait(&cond, &lock);
        pthread_mutex_unlock(&lock);
    }
}

void *consumer(void *args)
{
    while (1)
    {
        pthread_mutex_lock(&lock);
        printf("%d\n", queue[queueCounter - 1]);
        queueCounter--;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&lock);
        sleep(1);
    }
}

int main()
{
    system("clear");
    srand(time(NULL));
    pthread_t th[NUM_THREAD], th2[NUM_THREAD];

    for (int i = 0; i < NUM_THREAD; i++)
    {
        pthread_create(&th[i], NULL, &producer, NULL);
        pthread_create(&th2[i], NULL, &consumer, NULL);
    }

    for (int i = 0; i < NUM_THREAD; i++)
    {
        pthread_join(th[i], NULL);
        pthread_join(th2[i], NULL);
    }
}

【问题讨论】:

  • 在编写代码时,增加NUM_THREAD 是没有意义的。此外,您不会从线程中return,因此代码到处都有未定义的行为错误(就像您的编译器告诉您的那样)。
  • 我使用的是wsl linux所以我没有看到警告
  • 看看这产生的 CPU 负载。制作人会在不做那么多的情况下疯狂旋转。在一个好的实现中,CPU 应该保持大部分空闲。生产者/消费者的通常模式是有一个 FIFO 队列,你在那里的行为就像一个 LIFO 堆栈。 (您不会注意到随机数的差异,请尝试增加数字...)
  • @Lundin 我不增加 NUM_THREAD
  • @dratenik 我查了一下,你说得对,它会产生大量的 CPU 负载。我怎样才能解决这个问题?感谢您的帮助!

标签: c multithreading mutex


【解决方案1】:

如果你打算只使用一个线程,则不需要数组,无论如何,你创建两个线程但只有一个被连接(内存泄漏),而不是:

pthread_t th1[NUM_THREAD]; // or simply pthread_t th1;
pthread_t th2[NUM_THREAD]; // or simply pthread_t th2;

for (int i = 0; i < NUM_THREAD; i++)
{
    pthread_create(&th1[i], NULL, &producer, NULL);
    pthread_create(&th2[i], NULL, &consumer, NULL);
}

for (int i = 0; i < NUM_THREAD; i++)
{
    pthread_join(th1[i], NULL);
    pthread_join(th2[i], NULL);
}

【讨论】:

  • 我的愚蠢错误,thnx
  • 我改了代码你能查一下吗?
  • 现在好多了,不用浪费 cpu。两件小事:srand(time(NULL)); -> srand((unsigned)time(NULL));system(clear); 如果您正在寻找性能,这会很痛苦,因为您使用的是 unix,您可以使用控制台代码来清除屏幕:printf("\033[H\033[2J");
  • 完成,谢谢!