[SOLVED] Scanf and printf with Semaphore System V

Issue

I can’t understand why the output of my code is the following. It does not follow the logic I wrote in the program. I’m using System V semaphore to sync thread each others.

This program should simply require strings from standard input to the "main thread" and these should be written by child threads on files whose "pathname" is passed on to argv. FOR SIMPLICITY I removed this part and left only the scanf and printf, which resolved completely messed up by the logic of the program!

How do I solve it?

#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define fflush(stdin) while(getchar()!='\n') //REMOVE THIS
void *gestore(void *);
char buf[10];
struct info
{
        pthread_t tid[100];
        int v[100];
};
struct info TID;
union semun
{
        int val;
        struct semid_ds *buf;
        unsigned short *array;
        struct seminfo *__buf;
};
int indice;
int id_sem;
void *gestore(void *str)
{
        int fd, i, j;
        struct sembuf op[1];
        printf("Thread(%ld) CREATED\n",syscall(SYS_gettid));
        fflush(stdout);
        fd = open((char *)(str),O_CREAT|O_RDWR,0666);
        if(fd==-1)
        {
                printf("Error\n");
                return;
        }
        else
        {
                printf("File Opened\n");
                fflush(stdout);
        }
        repeat:
        op[0].sem_num=0;
        op[0].sem_op=-1;
        op[0].sem_op=0;
        semop(id_sem,op,1);
        printf("HELLO\n");
        fflush(stdout);
        for(i=0; i<5; i++)
        {
                if(write(fd,&(buf[2*i]),1)==-1)
                {
                        printf("ErroreWrite\n");
                        fflush(stdout);
                        return;
                }
                else
                {
                        printf("WRITED\n");
                        fflush(stdout);
                }

        }
        op[0].sem_num=1;
        op[0].sem_op=1;
        op[0].sem_op=0;
        semop(id_sem,op,1);
        goto repeat;

        if(close(fd)==-1)
        {
                printf("Errore close\n");
                return;
        }
        else
        {
                printf("File CLOSED\n");
                fflush(stdout);
        }

}



int main(int argc, char *argv[])
{
        if(argc<2)
        {
                printf("There must be at least 2 parameters\n");
                fflush(stdout);
                return -1;
        }
        int i;
        indice = argc;
        printf("Number of arguments:%d \n",argc);
        fflush(stdout);

        //SEM SYSTEM V

        union semun arg;
        struct sembuf op[1];
        id_sem = semget(6534,2,IPC_CREAT|0666);
        arg.val=0;
        semctl(id_sem,0,SETVAL,arg);
        arg.val=1;
        semctl(id_sem,1,SETVAL,arg);
        //////////////////////


        for(i=0; i<(argc-1); i++)
        {
                pthread_create(&(TID.tid[i]),NULL,gestore,argv[i+1]);
        }
        while(1)
        {
                op[0].sem_num=1;
                op[0].sem_op=-1;
                op[0].sem_op=0;
                semop(id_sem,op,1);

                for(i=0;i<5;i++)
                {
                        printf("Insert value(%d): \n",i);
                        fflush(stdout);
                        scanf("%c",&(buf[2*i]));
                        buf[2*i+1]='\0';
                        fflush(stdin);//USE while(getchar()!='\n');
                }

                op[0].sem_num=0;
                op[0].sem_op=1;
                op[0].sem_op=0;
                semop(id_sem,op,1);
        }

}

(a, b, c, d, e, f, g is my input from stdin)

Here is my output:

Number of arguments:4
a
Thread(1048) CREATED
Thread(1049) CREATED
Thread(1050) CREATED
b
File OPENED
c
File OPENED
d
File OPENED
e
f
HELLO
g
HELLO
h
WRITED
i
WRITED
l
WRITED
m
WRITED
n
WRITED
o
WRITED
p
WRITED
q
WRITED
e
WRITED
r
WRITED
s
a
s

Where is my string "Insert Value(%d)…"?

Replacing the macro defined by me with fflus (stdin) the following writing: while (getchar ()! = ‘N’); the output obtained is:

Number of arguments:4
Thread(1090) CREATED
Thread(1091) CREATED
Thread(1092) CREATED
File OPENED
File OPENED
HELLO
File OPENED
WRITED
HELLO
WRITED
WRITED
WRITED
WRITED
WRITED
WRITED
WRITED
WRITED
WRITED

In this case I got these outputs without sending any input characters.

Solution

Found the mystery. The triplet:

  • op[0].sem_num=0;
  • op[0].sem_op=-1;
  • op[0].sem_flg=0;

It was written everywhere badly in the following way:

  • op[0].sem_num=0;
  • op[0].sem_op=-1;
  • op[0].sem_op=0; <———

Also associated with the incorrect definition that other users pointed out to me was a disaster.

Thank you all!

Answered By – ABC

Answer Checked By – Willingham (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.