【问题标题】:While loop seems to stop checking the IF condition within unless I print something to stdout with thread虽然循环似乎停止检查 IF 条件,除非我用线程将某些内容打印到标准输出
【发布时间】:2022-10-25 21:50:44
【问题描述】:

所以我正在做一个项目,我遇到了一个奇怪的问题,我的循环似乎没有正确重复,但是如果我在 while 循环的开头添加一个 printf() ,它就可以完美地工作。 我以前做过同样的项目,但我正在重做,所以我参考了我以前的工作,看看我是否可以确定这个问题是从哪里引入的,但我似乎找不到任何我想念的东西导致问题。

这是被锁定的函数的代码。一个线程运行这个函数,而输入的其他线程将运行一个消费者函数。

void producer(int maxSize, char *outputFile){
    /**
     * @brief Main function for producer thread behaviour
     * Producer is in charge of creating new jobs and inserting them into the queue for the consumers to act on
     */
    string input;
    outOfInput = false;
    int timesLooped= 0;
    while(!outOfInput){
        int currentQueueSize = (int)jobQueue.size();
        timesLooped++;
        //if queue is smaller than max size
        if(currentQueueSize < maxSize){
            //read input from cin
            cin >> input;
            //check if eof has been reached
            if(cin.eof()){
                cout << "EOF" << endl;
                outOfInput = true;
            }
            //check input received
            //if Trans
            if(input[0] == 'T'){
                //add job time requirement to queue
                jobQueue.push(int(input[1]));
                int size = jobQueue.size();
                //release a waiting consumer if it exists
                pthread_cond_signal(&cond_empty);
                //print Work to the logfile
                //lock write mutex to prevent errors
                pthread_mutex_lock(&mutex_write);
                //open logFile in append mode
                logFile = fopen(outputFile, "a");
                fprintf(logFile, "WORK\n");
                std::fclose(logFile);
                //increment workCreated counter
                workCreated++;
                //unlock write mutex
                pthread_mutex_unlock(&mutex_write);
            //if Sleep
            }else if(input[0] == 'S'){
                //write Sleep to logfile
                //lock write mutex to prevent errors in writing
                pthread_mutex_lock(&mutex_write);
                //open in append
                logFile = fopen(outputFile, "a");
                fprintf(logFile, "SEEP\n");
                std::fclose(logFile);
                //increment timesSlept counter
                timesSlept++;
                //unlock write mutex
                pthread_mutex_unlock(&mutex_write);

                //sleep for requested time
                Sleep(int(input[1]));
            } 
        }
    }
    return;
}

基本上,似乎该函数卡在 if(currentQueueSize < maxSize) 好像队列大小没有得到重新检查,但是只要我在 if 语句上方添加 printf("literally any text") ,它就会按预期工作.

任何帮助将不胜感激,我觉得这一定是我想念的愚蠢的东西,但我不知道。这是消费者的代码,以防万一我在这里做错了,尽管我不认为这是因为 printf() 修复了它?

void *consumer(void *arguments){
    /**
     * @brief Main function for consumer thread behaviour
     * multiple consumer threads will handle asking for and completing work added by the producer thread
     */
    cons_arg_struct *cons_args = (cons_arg_struct*)arguments;
    long threadId = cons_args->threadId;
    char *outputFile = cons_args->outputFile;

    //Yay infinite looping
    while(true){
        //Time to clock in baby!
        //utilize write lock
        pthread_mutex_lock(&mutex_write);
        //open logfile in append
        logFile = fopen(outputFile, "a");
        fprintf(logFile, "ASKY\n");
        std::fclose(logFile);
        //unlock write mutex
        pthread_mutex_unlock(&mutex_write);

        //Is there any work for me up in here?
        //utilize a mutex for recieving work from queue to prevent doubling up;
        pthread_mutex_lock(&mutex_recieve);
        //check if queue is empty
        if(jobQueue.empty()){
            pthread_cond_wait(&cond_empty, &mutex_recieve);
        }
        //Ayo it's time to work babyyyyyy
        //take first value in queue and remove it from queue
        int Time = jobQueue.front();
        jobQueue.pop();
        //done recieving job, unlock
        pthread_mutex_unlock(&mutex_recieve);

        //print recieving information to logfile
        pthread_mutex_lock(&mutex_write);
        logFile = fopen(outputFile, "a");
        fprintf(logFile, "RECIVER\n");
        std::fclose(logFile);
        pthread_mutex_unlock(&mutex_write);

        //wOrkWorK woRkwork wOrkWork wORkworK wORKwOrk wORkwOrK woRkwork wOrKwORK wORkWORK wORKwoRk wORkWoRK
        Trans(Time);

        //print job finished to logfile
        pthread_mutex_lock(&mutex_write);
        logFile = fopen(outputFile, "a");
        fprintf(logFile, "FINFIN\n");
        std::fclose(logFile);
        pthread_mutex_unlock(&mutex_write);
    }
}

我知道,消费者线程目前没有退出条件。我只是还没有添加它。我试图让结果正确。 这是我现在得到的输出(\n 排除空间)

阿斯基 接收器 阿斯基 工作 工作 工作 工作 工作 工作 工作 工作 接收器 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 FINFIN 阿斯基 FINFIN 阿斯基

与预期结果(如果我添加 printf())

阿斯基 接收器 工作 工作 工作 工作 工作 阿斯基 接收器 工作 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 工作 工作 工作 工作 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 工作 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 FINFIN 阿斯基 FINFIN 阿斯基 工作 接收器 工作 工作 工作 工作 工作 接收器 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 工作 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 工作 接收器 工作 工作 工作 工作 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 渗透 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 FINFIN 阿斯基 FINFIN 阿斯基 工作 工作 接收器 接收器 工作 接收器 工作 工作 工作 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 工作 工作 工作 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 接收器 FINFIN 阿斯基 FINFIN 阿斯基 FINFIN 阿斯基 工作 工作

【问题讨论】:

  • 代码太多;没有人会为你筛选那么多。两个 cmets:由于存在输出语句(根本不会改变行为)导致的代码更改行为是未定义行为的常见表现(例如,取消引用错误的指针,对某些变量的未排序操作)。由于您正在使用线程和同步,因此可以肯定的是,代码中某些变量的并发操作没有正确同步。

标签: c++ multithreading pthreads mutex


【解决方案1】:

我相信你的问题出在线路上

cin >> input;

在您提到的条件语句中,挂起您的代码。

来自 cplusplus.com std::cin 参考的注释:

"表示标准输入流的 istream 类对象 面向窄字符(char 类型)。它对应于 C 流标准输入。”

cin 本身最适合用于高达 ' 的单个令牌 ' 字符,除非与继承自 std::istream 的成员函数配对,它仍将限制为类型为 char[n] 的静态大小。

您将希望使用std::getline 将数据的“类型字符串”添加到您的字符串容器变量“输入”中。以下是对std::getline 页面的引用。

https://en.cppreference.com/w/cpp/string/basic_string/getline

【讨论】:

    猜你喜欢
    • 2021-10-08
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多