【问题标题】:Scanf and printf with Semaphore System V使用 Semaphore System V 的 Scanf 和 printf
【发布时间】:2019-11-06 05:10:08
【问题描述】:

我不明白为什么我的代码输出如下。它不符合我在程序中编写的逻辑。我正在使用 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]='\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 是我从标准输入的输入)

在哪里我的字符串“插入值(%d)...”???

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

将我定义的宏替换为 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

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

【问题讨论】:

  • fflush(stdin); is undefined behavior. 自己编写并称其为 fflush() 是……有问题的。
  • #define fflush(stdin) while(getchar()!='\n') 看起来是个非常糟糕的主意...
  • 请翻译打印输出,最好也翻译标识符。它使不懂您的母语的人更容易为您提供帮助。
  • @AndrewHenle 我进行了更改,但我的问题仍然存在。我认为问题出在信号量上,但为什么呢?

标签: c multithreading unix printf semaphore


【解决方案1】:

找到了奥秘。三胞胎:

  • 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;

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

谢谢大家!

【讨论】:

    【解决方案2】:

    不知道它是否能解决您的问题,但您的代码与您的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 中保留的。

    【讨论】:

    • 好的,谢谢,我做了更改,但我的问题仍然存在。
    • @AAA 我尝试运行你的代码,但由于我不理解我放弃的打印输出。
    • 难道你不理解印刷品的意思吗?你不明白为什么会出现这个订单?
    • @AAA 我根本看不懂印刷品,而且我非常不愿意尝试解码不是用英文写的东西。我编译并运行了你的代码,但是当我看到所有的打印输出都是西班牙语时?我只是放弃了。另外,请不要更改代码,因为这会使答案无效。我现在已经回滚了。
    • 我用英文重写版画,对​​不起
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 2017-11-26
    相关资源
    最近更新 更多