使用信号量系统 V 的 Scanf 和 printf

Scanf and printf with Semaphore System V

我不明白为什么我的代码输出如下。它不遵循我在程序中编写的逻辑。我正在使用 System V 信号量 来相互同步线程。

这个程序应该只需要从标准输入到“主线程”的字符串,这些字符串应该由子线程写入其“路径名”传递给 argv 的文件。为了简单起见,我删除了这部分,只留下了 scanf 和 printf,这完全被程序的逻辑搞砸了!

如何解决?

#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]='[=10=]';
                        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 是我从标准输入输入的)

这是我的输出:

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

我的字符串“Insert Value(%d)...”在哪里?

将我定义的宏替换成fflus(stdin)如下写法:while(getchar()!='N');获得的输出是:

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

在这种情况下,我没有发送任何输入字符就获得了这些输出。

不知道它是否能解决您的问题,但您的代码存在严重缺陷 define。这不仅会让知道刷新标准输入是大忌的读者感到困惑。它还会更改对 fflush 的所有调用,无论参数如何。下面是一个 Hello World 程序来演示:

#include <stdio.h>
#define fflush(stdin) printf("Hello, World!\n")

int main(void)
{
    // Will call above macro despite the fact that I'm trying to flush stdout
    fflush(stdout);
}

如果您想使用宏,请执行以下操作:

#define FLUSH_STDIN while(getchar()!='\n')

但是除非你有充分的理由使用宏,否则请使用函数:

void flush_stdin(void) { while(getchar()!='\n'); }

我还建议不要使用以下划线 (struct seminfo *__buf;) 开头的标识符,因为这些在 C 中是保留的。

发现了其中的奥秘。三胞胎:

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

到处都写得很烂,如下:

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

还与其他用户向我指出的错误定义相关联是一场灾难。

谢谢大家!