Совместное использование ограниченного буфера с блокировками Pthread и mutex в ожидании - PullRequest
0 голосов
/ 20 октября 2019

Я пытаюсь создать потребительскую очередь производителей, используя блокировки мьютекса, создавая занятое ожидание между потоками. Мой основной файл принимает X целочисленных аргументов и помещает их в ограниченный буфер размером 50. Я использую цикл while для этого, поскольку вы не знаете сумму заранее. Я не уверен, когда и где создать ветку моего продюсера. ПРИМЕЧАНИЕ: Main - это «продюсер» в том смысле, что он заполняет буфер, но моя фактическая функция продюсера будет позже передаваться моей функции-потребителю в моем коде, поэтому игнорируйте имена. Мэйн собирается «Производить» числа нажатием, а производитель собирается вывести эти числа для дальнейшего использования. У меня вопрос: где и когда я делаю свой Pthread_create в своем коде для производителя, и правильно ли я использую блокировки Mutex для синхронизации между двумя потоками?

#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);
}

1 Ответ

0 голосов
/ 22 октября 2019

Мой вопрос: где и когда я делаю свой Pthread_create в своем коде для продюсера, и правильно ли я использую блокировки Mutex для синхронизации между двумя потоками?

Покавсе правильно инициализировано и синхронизировано, вы можете позвонить pthread_create() куда угодно, в том числе и в определенную программу. Но, по крайней мере, две вещи неверны:

  • pc_pop() ведет себя неопределенно (return неинициализированного значения), если в буфере нет числа для всплывающего окна.
  • СdataStruct->count доступен producer() без блокировки, объявление должно быть _Atomic(int) count;.
...