1

I am trying to write a program with threads, but i think i am not fully understanding them. I've been studying and working on the code for 8 hours straight and my head blocked. This is my task: i have 5 workers (threads) and i must use them to gather resources so i can build barracks and train 20 soldiers. SOldiers and barracks cost resources, so i must first gather resources in order to train a solder and/or build a barrack. I must use condVars and mutexes to protect the data and sync the threads (this i think is the hardest for me). This is my code so far:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXCOUNT 100
pthread_mutex_t the_mutex;
pthread_mutex_t the_mutex_base;
pthread_cond_t condp, condc;
int allResources = 4096;
int gatheredResouerces = 0;
int soldiers=0;
int barracks = 0;




void* work(void* ptr){
     size_t thread_num = (size_t)ptr;

    while(1){

        if(allResources>0&&(soldiers+5)<MAXCOUNT){

            getResources(thread_num);
            transport(thread_num);
            unload(thread_num);

        }
        else{
            printf("NOt enough resources...Quitting");
            break;
        }
    }
}

void getResources(size_t thread){

    printf("Worker %zd is searching...\n",thread);

    pthread_mutex_lock(&the_mutex);
    pthread_cond_wait(&condp,&the_mutex);
    // while (gatheredResouerces != 0)
      // pthread_cond_wait(&condp, &the_mutex);

        gatheredResouerces+=5;
        allResources-=5;
        //pthread_cond_broadcast(&condc);
        pthread_mutex_unlock(&the_mutex);
        //pthread_cond_timedwait(&condp, &the_mutex,3);
    return 0;

}

void build(size_t thread){

    printf("Worker %zd is building a barrack",thread);
    pthread_mutex_lock(&the_mutex);

    while (gatheredResouerces == 0);
      pthread_cond_wait(&condc, &the_mutex);


    barracks++;
    gatheredResouerces-=100;
    pthread_mutex_unlock(&the_mutex);
    sleep(20);
    printf("worker %zd completed new building\n",thread);
    return 0;
}

void transport(size_t thread){
    printf("Worker %zd is transporting\n",thread);
    pthread_mutex_lock(&the_mutex_base);
    sleep(3);
    pthread_mutex_unlock(&the_mutex_base);

}

void unload(size_t thread){
    printf("Worker %zd unloaded resources\n",thread);
    sleep(1);
    return 0;
}


int main(int argc, char **argv)
{
    pthread_t threads[5];


    pthread_mutex_init(&the_mutex, NULL);
    pthread_cond_init(&condp, NULL);
    pthread_cond_init(&condc, NULL);

    for(int i=0;i<5;i++){
      int errorOne = pthread_create(&threads[i], NULL,work,(void*)i);

        if (errorOne != 0) {
            printf("Error creating thread %zd: error");
        }
    }


    for (int i = 0; i<5; i++) {
        printf("Waiting for thread %d to finish..\n", i);
        int error = pthread_join(threads[i], NULL);
        if (error != 0) {
            printf("Error joining thread %zd: error:",threads[i]);
        }
    }*/


    pthread_exit(NULL);

    printf("\t\t\t...GAME INFORMATION...\n");
    printf("gathered resources:%d\n",gatheredResouerces);
    printf("Initial resources:%d\n",allResources);
    printf("Resources left:%d",allResources-gatheredResouerces);

    return 0;
}

I am very new to programming, so i am absolutely sure that so far my code is rubbish. Obviously it is not working, most of the times one thread gets to the work function and i get a segmantation fault. Some more on the condition: Workers must unload the resources in a command base and only one can do it at a time. I did not fully understand how to do this, is it a condVar that i lock and unlock in order to "unload resources"? Also, i am pretty sure i am screwing all the functions and not using these threads and mutexes properly, i read everything about threads, but all the examples are pretty easy - just for example a print function and a main function with 2-3 threads. I have no idea how to sync all these threads and make them do all these things. Also, if we type S or B worker should start either Building a barrack, or train a Soldier - this i also do not know how achieve, because it is undependable of the worker's process. What i mean is during the time worker is "working" if we type B or W if there are resources available worker should jump to other function - either Build or Train(which i havent written yet), if we dont have resources, worker should continue his resource gathering. I will be very happy if someone enlighten me where i am wrong, i know there are probably alot of mistakes, but i am really trying to learn. Thank you. Here is an example of a working program:

Game begins! Worker 1 is searching

Worker 1 is transporting

Worker 1 unloaded resources to Base station

Worker 2 is searching

Worker 2 is transporting

Worker 2 unloaded resources to Base station W Operation not supported

Worker 3 is searching

Worker 3 is transporting

Worker 3 unloaded resources to Base station

….. b Not enough resources

Worker 4 is searching

Worker 4 is transporting

Worker 4 unloaded resources to Base station … b Worker 3 is constructing new building barracks

Worker 2 is searching

Worker 2 is transporting

Worker 2 unloaded resources to Base station

…. Worker 3 completed new building barracks w

Warrior is being trained Worker 3 is searching

Warrior is ready for duty

...

  • Your code doesn't compile, at least not with gcc – Rogus Apr 25 '17 at 05:03
  • I am compiling it with codeblocks for linux. I am seeing only worker 1 is searching and worker 2 is searching, code stops there. I guess it is a somekind of a deadlock...? no idea how sync these threads :( – Krasimir Yordanov Apr 25 '17 at 05:09
  • what is `condc` and what is `condp`? What are these conditions supposed to do? Which one is used for what? – Rogus Apr 25 '17 at 05:10
  • As far as i understoond i must use them in order to lock/unlock the use of a variable. Maybe i am wrong? What i am trying to say is i read that i must use them to signal a thread when it can use for example gatheredResources variable. If the variable is already in use from another thread, the thread should wait until a signal is received. – Krasimir Yordanov Apr 25 '17 at 05:12
  • You should call pthread_attr_setstacksize prior to starting thread so that you dont run out of stack allocated to thread handler – Pras Apr 25 '17 at 06:12
  • On entry to `work()` each thread ends up calling `getResources()` which calls `pthread_cond_wait()`. Nothing is calling `pthread_cond_signal()` or `pthread_cond_broadcast()` so all your threads are going to end up blocking on the condition variable. – Tom Parkin Apr 25 '17 at 11:13

1 Answers1

0

I do not yet have 50 rep, otherwise I would add this as a comment to your original post.

What is a mutex?

The link leads to a golden question/answer and since you mentioned having problems with synchronization, it might be useful. If you have more specific, narrower questions, I'll try to be of more help. I'm currently in a position where I cannot run code, unfortunately, but logic on the other hand...

Community
  • 1
  • 1
Ardemis
  • 139
  • 9