c ++多线程消费者在生产者完成生产后开始休眠

时间:2017-12-02 02:29:27

标签: c++ multithreading

我正在尝试测试简单的自编并发队列。如果有足够的空间(queue.size< maxSize),生产者线程正在从输入文件读取数据并将其推送到队列。消费者从队列中获取数据并将其写入输出文件。 它在开始时工作正常。制作人立即用项目填充队列并等待。消费者从队列中获取一个项目,生产者立即推送另一个项目,因为队列有足够的空间。 当生产者到达EOF时出现问题 - 消费者停止处理队列中的项目。

template <class T>
class ConcurrentQueue
{
public:
ConcurrentQueue(){};
~ConcurrentQueue(){};
void push(T item)
{
    std::unique_lock<std::mutex> locker(queueMtx);
    cv.wait(locker, [this]()->bool{return dataQueue.size() < maxSize;});
    if(dataQueue.size() < maxSize) //Avoiding spurious wakeup
        dataQueue.push(item);
    std::cout << "Pushed " << item << "\n";
    cv.notify_all();
}
void popFront()
{

    std::unique_lock<std::mutex> locker(queueMtx);
    cv.wait(locker, [this]()->bool{return !dataQueue.empty();});
    if(!dataQueue.empty()){ //Avoiding spurious wakeup
        std::cout << "Popping item " << dataQueue.front() << "\n";
        dataQueue.pop();
    }
    cv.notify_all();
}
T getFront()
{
    std::unique_lock<std::mutex> locker(queueMtx);
    cv.wait(locker, [this]()->bool{return !dataQueue.empty();});
    if(!dataQueue.empty()) //Avoiding spurious wakeup
        return dataQueue.front();
}
bool isEmpty()
{
    std::unique_lock<std::mutex> locker(queueMtx);
    cv.wait(locker);
    return dataQueue.empty();
}
private:
std::queue<T> dataQueue;
std::mutex queueMtx;
std::condition_variable cv;
static const uint8_t maxSize;
};

template <class T>
const uint8_t ConcurrentQueue<T>::maxSize = 3;

class ConcurrentFactorizator
{
public:
ConcurrentFactorizator(const std::string &input, const std::string &output, size_t poolSize)
        : inputFile(input), outputFile(output), pool(poolSize) {};
~ConcurrentFactorizator(){};
void processFile()
{
    std::ifstream fin(inputFile);
    std::ofstream fout(outputFile);
    if(!fin.good())
        throw std::runtime_error("Unable to read input file");
    if(!fout.good())
        throw std::runtime_error("Unable to open/create output file");

    //Input file contains: 2565728359 172494884245 139104056346 1235266377788 527499235299 185919010598 3615785591950

    std::thread producerThread([this, &fin](){
        T value;
        while(fin >> value){
            numbersQueue.push(value);
        }
        std::cout << "File done. Finished reading" << std::endl;
        fin.close();
    });

    std::thread consumerThread([this, &fout](){
        while(!numbersQueue.isEmpty())
        {
            fout << numbersQueue.getFront() << std::endl;
            numbersQueue.popFront();
        }
        std::cout << "Queue now is empty, finishing!" << std::endl;
    });

    producerThread.join();
    consumerThread.join();

    fout.close();

}
private:
std::string inputFile;
std::string outputFile;
ConcurrentQueue<T> numbersQueue;
Threadpool pool; //This one will be used when I will be able to fix the problem
};

的main.cpp

int main()
{

ConcurrentFactorizator<uint64_t> fact("input.txt","output.txt", 5);
try
{
    fact.processFile();
}
catch (std::exception &e)
{
    std::cout << e.what() << std::endl;
}

return 0;
}

COUT:

Pushed 2565728359
Pushed 172494884245
Pushed 139104056346
Popping item 2565728359
Pushed 1235266377788
Popping item 172494884245
Pushed 527499235299
Popping item 139104056346
Pushed 185919010598
Popping item 1235266377788
Pushed 3615785591950
File done. Finished reading
Popping item 527499235299

输出文件

2565728359
172494884245
139104056346
1235266377788
527499235299

0 个答案:

没有答案