1
\$\begingroup\$

I am on the learning curve of C and its capabilities. Below I have tried to create 4 individual programs where the execution is always in order (program 0,1,2,3).

About the program
Program #0 is always executed (called) first, it also creates semid's
Program #1 can ONLY be executed if Program #0 has ran
Program #2 can ONLY be executed if Program #1 has ran
Program #3 can ONLY be executed if Program #2 has ran

What Do I Need?
Since, I am a beginner I thought an expert's knowledge on creating a better design or code structuring would help me.

Program Call
./prog0 && ./prog1 && ./prog2 && ./prog3

Program #0

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/sem.h>

int
main ( )
{
    int semid;
    key_t key;
    union semun arg;

    key = ftok("program0.c", 'a');
    semid = semget(key, 3, 0666 | IPC_CREAT);
    if ( semid < 0 )
    {
        perror("Could Not Created The Requested Semaphore");
        exit(1);
    }
    arg.val = 1;
    semctl(semid, 0, SETVAL, arg);
    arg.val = 0;
    semctl(semid, 1, SETVAL, arg);
    semctl(semid, 2, SETVAL, arg);
    printf("Executing process #0.\n");
    return 0;
}

Program #1

int
main ( )
{
    int semid, key;
    union semun arg;
    key = ftok("program0.c", 'a');
    semid = semget(key, 3, 0666 | IPC_CREAT);
    if ( semid < 0 )
    {
        perror("Could Not Created The Requested Semaphore");
        exit(1);
    }
    if ( semctl(semid, 0, GETVAL, 0) != 1 )
    {
        semctl(semid, 0, IPC_RMID);
        exit(1);
    }
    printf("Executing process #1.\n");
    arg.val = 0;
    semctl(semid, 0, SETVAL, arg);
    arg.val++;
    semctl(semid, 1, SETVAL, arg);
    return 0;
}

Program #2

int
main ( )
{
    int semid, key;
    union semun arg;
    key = ftok("program0.c", 'a');
    semid = semget(key, 3, 0666 | IPC_CREAT);
    if ( semid < 0 )
    {
        perror("Could Not Created The Requested Semaphore");
        exit(1);
    }
    if ( semctl(semid, 1, GETVAL, 0) != 1 )
    {
        semctl(semid, 0, IPC_RMID);
        exit(1);
    }
    printf("Executing process #2.\n");
    arg.val = 0;
    semctl(semid, 1, SETVAL, arg);
    arg.val++;
    semctl(semid, 2, SETVAL, arg);
    return 0;
}

Program #3

int
main ( )
{
    int semid, key;
    key = ftok("program0.c", 'a');
    semid = semget(key, 3, 0666 | IPC_CREAT);
    if ( semid < 0 )
    {
        perror("Could Not Created The Requested Semaphore");
        exit(1);
    }
    if ( semctl(semid, 2, GETVAL, 0) != 1 )
    {
        semctl(semid, 0, IPC_RMID);
        exit(1);
    }
    printf("Executing process #3.\n");
    semctl(semid, 0, IPC_RMID);
    return 0;
}
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

Programs exit instead of wait

Right now, your programs check their semaphore, but if they don't find the value they are expecting, they exit instead of wait. I think that you should modify your programs to wait until the previous program signals them. You would need to make the following modifications:

  1. In program #0, initialize each semaphore to the value 1.
  2. In each other program, use semop() to wait for its semaphore to reach value 0. For example, program #1 waits for semaphore #0's value to become 0, using semop().
  3. Modify each program to actually take a non-zero amount of time to do its work. I suggest a for loop like this:

    for (int i=0;i<10;i++) {
        printf("Executing process #1, iteration #%d.\n", i);
        sleep(1);
    }
    
  4. After each program's work loop, it releases its semaphore using semop(). This causes the semaphore value to transition from 1 to 0, which allows the next program to run. For example, program #1 releases semaphore #1, causing program #2 to be able to run.
  5. Program #3 cleans up instead of releasing a semaphore.
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.