Ларри, Мо, Керли Взаимное исключение

Постановка задачи:

«Ларри, Мо и Керли сажают семена. Ларри выкапывает лунки. Затем Мо кладет семя в каждую лунку. Затем Керли засыпает яму. Есть несколько ограничений синхронизации:

  • Мо не может посадить семя, если не существует хотя бы одной пустой лунки, но Моу все равно, насколько Ларри опережает Мо.
  • Кудрявый не может заполнить дыру, если не существует хотя бы одной дыры, в которую Мо посадил семя, но эта дыра еще не заполнена. Керли все равно, насколько Мо опережает Керли.
  • Керли заботится о том, чтобы Ларри не получил больше, чем МАКС. дырок, впереди Керли. Таким образом, если есть МАКСИМАЛЬНОЕ количество незаполненных отверстий, Ларри придется подождать.
  • Есть только одна лопата, которой и Ларри, и Керли нужно копать и засыпать ямы соответственно.

Разработайте, внедрите и протестируйте решение этой проблемы IPC, которое представляет Ларри, Керли и Мо. Используйте семафоры в качестве механизма синхронизации».

Я набрал программу из какого-то псевдокода, который мне дали, но я получаю сообщение об ошибке:

project2part3.c:13:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion] 
 #define MAX 5
             ^
project2part3.c:22:18: note: in expansion of macro 'MAX'
 sem_t unfilled = MAX;
                   ^
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

#define MAX 5

void *larry();
void *moe();
void *curly();

pthread_mutex_t shovel = PTHREAD_MUTEX_INITIALIZER;
sem_t empty;
sem_t seeded;
sem_t unfilled;

int main(){
    pthread_t ltid;
    pthread_t mtid;
    pthread_t ctid;
    //initializing the semaphores
    sem_init(&empty, 0, 0);
    sem_init(&seeded, 0, 0);
    sem_init(&unfilled, 0, 0);

    pthread_create(&ltid, NULL, larry, NULL);  //create the larry thread
    pthread_create(&mtid, NULL, moe, NULL);  //create the moe thread
    pthread_create(&ctid, NULL, curly, NULL);  //create the curly thread

    pthread_join(ltid,NULL);
    pthread_join(mtid,NULL);
    pthread_join(ctid,NULL);
}

void *larry(){
    while(1){
        sem_wait(unfilled);
        sem_wait(shovel);
        //Dig the hole
        printf("Digging");
        sem_post(shovel);
        sem_post(empty);
    }
}

void *moe(){
    while(1){
        sem_wait(empty);
        //Seed the hole
        printf("Seeding");
        sem_post(seeded);
    }
}

void *curly(){
    while(1){
        sem_wait(seeded);
        sem_wait(shovel);
        //Fill the hole
        printf("Filling");
        sem_post(shovel);
        sem_post(unfilled);
    }
}

person Tangwheeler    schedule 04.03.2016    source источник
comment
На какую строку указывает ошибка? Показать полный текст ошибки   -  person sabbahillel    schedule 04.03.2016
comment
Функции объявлены как void*, но не возвращают никаких значений. Рыбный. Также main ничего не возвращает. Также функции, не принимающие параметры, должны быть объявлены как (void). Я бы сказал, что вы должны получать гораздо больше предупреждений.   -  person Eugene Sh.    schedule 04.03.2016
comment
sem_t unfilled = MAX; Это не то, как вы инициализируете семафор...   -  person Dark Falcon    schedule 04.03.2016
comment
Как будто компилятор сообщает вам точное местоположение и точную ошибку, а вы спрашиваете, что не так?   -  person Eugene Sh.    schedule 04.03.2016
comment
@EugeneSh., main без явного возврата неявно возвращает 0. Это замечательная функция, которая экономит мне около 10 нажатий клавиш каждый раз, когда я пишу main.   -  person eran    schedule 04.03.2016
comment
@eran Я думаю, что это неправда. Значение, возвращаемое без явного оператора return, не определено. Обновление: stackoverflow.com/questions/3727051/   -  person Eugene Sh.    schedule 04.03.2016
comment
@ЕвгенийШ. Он действительно возвращает 0 в соответствии со стандартом, но не неявно возвращает EXIT_SUCCESS, что, в отличие от 0, может вызвать проблемы.   -  person Daniel Jour    schedule 04.03.2016
comment
@DanielJour Ну, это сложный момент. Я бы не стал экономить на этом 10 нажатий клавиш.   -  person Eugene Sh.    schedule 04.03.2016
comment
@ЕвгенийШ. Я тоже не такой ленивый. Но некоторые... ну, хорошая тема для флейм вара :D   -  person Daniel Jour    schedule 04.03.2016
comment
размещенный код при подаче на компилятор заставляет компилятор выводить 20 операторов ошибок и предупреждений. (используя gcc -c -Wall -Wextra -Wconversion -pedantic -std=gnu99 filename.c -o filename.o -I. -I/usr/include )   -  person user3629249    schedule 06.03.2016


Ответы (1)


sem_t shovel = 1; // Note: Is a lock in the updated question code
sem_t empty = 0;
sem_t seeded = 0;
sem_t unfilled = MAX;

Это не то, как вы инициализируете семафоры. Это сложные вещи, а не просто счетчики, которым можно назначить. Вот почему есть функция sem_init, которую вы используете, но не правильно. Прочитайте об этом в справочнике по вашему выбору.

IIRC sem_t - это определение типа, похожее на

typedef struct whatever * sem_t;

Таким образом, каждая из приведенных выше строк инициализирует указатель из целого числа.

Кроме того, ваши функции должны возвращать то, что вы объявили для их возврата. Это особенно верно для функций, используемых для потоков: они (должны) объявлять, что возвращают указатель void, поэтому (если у вас нет ничего значимого для возврата) просто используйте

return NULL;

в конце досягаемости этих.

Более того:

pthread_create(&btid, NULL, larry, NULL);  //create the larry thread
pthread_create(&btid, NULL, moe, NULL);  //create the moe thread
pthread_create(&btid, NULL, curly, NULL);  //create the curly thread

Вам нужны эти вызовы к разным thread_t, а не к одному и тому же (btid).

person Daniel Jour    schedule 04.03.2016
comment
примечание: опубликованный код объявляет shovel как pthread_mutex, а НЕ как семафор, поэтому каждая ссылка на лопату должна использовать функции pthread_mutex_lock() или pthread_mutex_unlock(), а не semwait() и не sempost() - person user3629249; 06.03.2016
comment
@user3629249 user3629249 Действительно, я добавил примечание. Я планирую сохранить его, поскольку он напоминает исходный код вопроса и лучше согласуется с остальным кодом вопросов. - person Daniel Jour; 06.03.2016