1

I am trying to write a code, which output should create a molecule. Always two hydrogen will be taken and one oxygen and then one molecule will be created. There is still so much to do so many of variables you probably wont understand but I cant move because I get segmentation fault all the time I try to do something with semaphores, and I don't know if I am doing something wrong in initializing them. Or I am doing it badly and there is some other more efficient way?

#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <semaphore.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <stdbool.h>

typedef struct parametry{
    int NO; // pocet kysliku
    int NH; // pocet vodiku
    int TI; // Maximální čas milisekundách, po který atom kyslíku/vodíku po svém vytvoření čeká, než se zařadí do fronty na vytváření molekul. 0<=TI<=1000
    int TB; // Maximální čas v milisekundách nutný pro vytvoření jedné molekuly. 0<=TB<=1000
} Tparams;

FILE *file;

sem_t *hydrogen;
sem_t *oxygen;
sem_t *barrier_1;



int param_write(int argc, char **argv, Tparams *parametry)
{
    bool wrong_arguments = false; // pokud jsou argumenty spatne vykona exit
    if(argc > 5)
    {
        fprintf(stderr, "Moc argumentu\n");
        exit (1);
    }
    if(argc < 5)
    {
        fprintf(stderr, "Malo argumentu\n");
        exit (1);
    }
    parametry->NO = atoi(argv[1]);
    parametry->NH = atoi(argv[2]);
    parametry->TI = atoi(argv[3]);
    parametry->TB = atoi(argv[4]);

    if(parametry->NO <= 0)
    {
        fprintf(stderr, "Spatne zadany argument NO\n");
        wrong_arguments = true;
    }
    if(parametry->NH <= 0)
    {
        fprintf(stderr, "Spatne zadany argument NH\n");
        wrong_arguments = true;
    }
    if(parametry->TI < 0 || parametry->TI > 1000)
    {
        fprintf(stderr, "Spatne zadany argument TI\n");
        wrong_arguments = true;
    }
    if(parametry->TB < 0 || parametry->TB > 1000)
    {
        fprintf(stderr, "Spatne zadany argument TB\n");
        wrong_arguments = true;
    }
    if(wrong_arguments)
    {
        exit (1);
    }

    return 0;
}

int file_control()
{
    if((file = fopen("proj2.out", "w")) == NULL) 
    {
        fprintf(stderr, "Chyba s suborem\n");
        exit(1);
    }
    return 0;
}

void hydrogen_process(int idH,int *hyd_count)
{
    idH++;
    sem_wait(hydrogen);
    printf("H %d: started\n", idH);
    printf("H %d: going to queue\n", idH);
    (*hyd_count)++;
    if((*hyd_count) == 2)
    {
        sem_post(oxygen);
        (*hyd_count) = 0; 
    }

    
}

void oxygen_process(int idO)
{
    sem_wait(oxygen);
    printf("O %d: started\n", idO);
    printf("O %d: going to queue\n", idO);
    printf("Molecule created\n");
    sem_post(hydrogen);
    sem_post(hydrogen);
}

int main (int argc, char **argv)
{
    Tparams parametry;
    file = fopen("proj2.out","w");
    param_write(argc, argv, &parametry);
    file_control();

    pid_t pid_process;
    pid_t pid_ox;
    pid_t pid_hyd;
   

    sem_init(hydrogen, 1, 2);
    sem_init(oxygen, 1, 0);
    sem_init(barrier_1, 1, 1);

    int hyd_count = 0;
   
    pid_process = fork();
    if(pid_process < 0)
    {
        fprintf(stderr, "Chyba pri volani funkce fork");
        fclose(file);
        exit (1);
    }
    else if(pid_process == 0) // child
    {
        for(int i = 0; i < parametry.NO;i++)
        {
            usleep((random() % (parametry.TI + 1))*1000);   
            pid_ox = fork();
            if(pid_ox < 0) 
            {
                fprintf(stderr, "Chyba pri volani funkce fork");
                fclose(file);
                exit (1);
            }
            if(pid_ox == 0)
            {  
                oxygen_process(i);
                exit (0);
            }else
            {
               
            }
        }
    }else if(pid_process > 0) // parent
    {
        for(int i = 0; i < parametry.NH;i++)
        {
            usleep((random() % (parametry.TI + 1))*1000);
            pid_hyd = fork();
            if(pid_hyd < 0) 
            {
                fprintf(stderr, "Chyba pri volani funkce fork");
                fclose(file);
                exit (1);
            }else if(pid_hyd == 0)
            {
                hydrogen_process(i, &hyd_count);
                exit (0);
            }else
            {
                 
            }
        }
    }
    sem_destroy(hydrogen);
    sem_destroy(oxygen);
    sem_destroy(barrier_1);
 
    fclose(file);
    return 0;
}
1
  • 1
    Your semaphores are not allocated. You are passing NULL pointers to the sem_* functions. Look around for some usage examples. Commented Apr 26, 2022 at 13:57

1 Answer 1

1

Seg faults are probably due to the fact that you are using uninitialized pointers to sem_t, with no memory allocated for them to point to. sem_init doesn't allocate memory for the sem type itself.

I'd start with:

sem_t hydrogen;
sem_t oxygen;
sem_t barrier_1;

Then pass around references to these in your sem_ API. Example:

sem_init(&hydrogen, 1, 2);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.