c - 与 Pthread 共享有界缓冲区和互斥锁忙等待

标签 c multithreading synchronization buffer mutex

我正在尝试创建一个生产者消费者队列,使用互斥锁,在线程之间创建繁忙等待。我的主文件采用 X 数量的整数参数,将它们推送到大小为 50 的有界缓冲区中。我使用 while 循环来执行此操作,因为您事先不知道数量。我不确定何时何地创建我的生产者线程。 注意:Main 是一个“生产者”,因为它填充了缓冲区,但我的实际生产者函数将在稍后的代码中传递到我的消费者函数,因此请忽略名称。 Main 将通过推送来“生产”数字,而生产者将弹出这些数字以供以后使用。我的问题是我何时何地在生产者代码中创建 Pthread_create 以及我是否正确使用互斥锁来实现两个线程之间的同步?

#include <pthread.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#define BUFFER_SIZE (50)

typedef struct {
        int buffer[BUFFER_SIZE];
        int count;
        int top;
        int next;
        pthread_mutex_t count_lock;
} prodcons;

void pc_init(prodcons *pc);
int pc_pop(prodcons *pc);
void pc_push(prodcons *pc, int val);

void factor2pc(prodcons *pc, int number);
void *producer(void *data);
void *consumer(void *data);

int main(int argc, char *argv[])
{
        int index = 1;
        int num;
        prodcons pc_nums;



        //pthread_t tid[argc - 1];
        pthread_t tid;
        pthread_attr_t attr;

        if (argc <  2) {
                fprintf(stderr, "usage: No arguments\n");
                return -1;
        }
        if (atoi(argv[1]) <= 0)
        {
                fprintf(stderr, "%d not > 0 or you must provide a positive integer.\n", atoi(argv[1]));
                return -1;
        }


        pthread_attr_init(&attr);


        pc_init(&pc_nums);


        //DO I PUT THIS HERE or WHILE LOOP?
        pthread_create(&tid, &attr, *producer, &pc_nums);

        while (index < argc)
        {
                num = atoi(argv[index]);
                pc_push(&pc_nums, num);
                index++;
        }

}

void *producer(void *data)
{
        prodcons *dataStruct = data;







        while (dataStruct->count < BUFFER_SIZE)
        {
                number = pc_pop(data);
                //This print is just here to make sure I am correctly "poping" from buffer
                printf("%d\n", number);
        }
}

void pc_init(prodcons *pc)
{
        pc->count = 0;
        pc->top = 0;
        pc->next = 0;
        if (pthread_mutex_init(&pc->count_lock, NULL) != 0)
        {
        printf("\n mutex init has failed\n");
        }
}


int pc_pop(prodcons *pc)
{
        int val;
        pthread_mutex_lock(&pc->count_lock);

        if (pc->count > pc->top)
        {
                val = pc->buffer[pc->count];
                printf("%d\n", val);
                pc->buffer[pc->count] = 0;
                pc->count--;
        }

        pthread_mutex_unlock(&pc->count_lock);
        return val;
}

void pc_push(prodcons *pc, int val)
{
        pthread_mutex_lock(&pc->count_lock);

        if (pc->count < BUFFER_SIZE)
        {
                pc->buffer[pc->count] = val;
                pc->count++;
        }

        pthread_mutex_unlock(&pc->count_lock);
}

最佳答案

My question is where and when do I make my Pthread_create in my code for producer and am I using the Mutex locks correctly to have synchronization between the two threads?

只要正确初始化和同步,您就可以将 pthread_create()在您想要的任何地方调用,包括它在给定程序中的放置位置。但至少有两件事是错误的:

  • pc_pop()如果缓冲区中没有要弹出的数字,则行为未定义(由 return 为未初始化值)。
  • dataStruct->count通过 producer() 访问如果没有锁定,声明应该是 _Atomic(int) count; .

关于c - 与 Pthread 共享有界缓冲区和互斥锁忙等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58476863/

相关文章:

java - 我可以使用方法的哪些属性来检查它是否是线程安全的?

html - 在 HTML5 本地存储上实现同步原语

c - 使用 stddef.h 的 offsetof 而不是自己滚动的可移植性

c++ - 如果数据已经发送,为什么 select 只将文件描述符显示为就绪?

vb.net - VB.Net 中的线程安全

c++ - 如何避免线程+优化器==无限循环?

multithreading - 为什么名称为 "monitor"?

java - java中的File.delete是否执行文件锁定?

java - BACnet PC 应用程序 :How to inquiry list of BACnet TCP/IP objects

c - 从 stdin 读取 execv 的参数? (C)