C++ 具有唯一锁定的并发解析和过滤
我想阅读一个xml文档,过滤我不想要的任何东西(过滤不是问题的一部分),然后写回cout或ofstream 但是,我希望同时执行此操作的方式如下:Thread1(解析器)读取xml文件,一次读取一行(代码中的std::string行),然后将该行提供给thread2,thread2的唯一任务是过滤该行。完成后,它将该行提供回thread1,以写入输出 然而,我现在的程序一点也不安全。首先,有时thread2能够首先获取互斥锁,即使我执行std::unique_lock locker(mu,defer_lock),或者甚至让thread2等待100毫秒,我也会收到一个错误:std::this_thread::sleepfor(100ms)。我不知道如何确保互斥体的获取首先由thread1完成 一个更重要的问题是,即使thread1首先获取互斥锁,我也会在程序读取文档的第一行之后,在function2的line locker.unlock()处出错。搜索此错误时,似乎我正在尝试解锁已解锁的互斥锁。函数2中unique_lock的初始化不应该锁定互斥锁吗 最后,我认为我可能使用了错误的资源,或者我的程序结构是错误的。我可以有一些建议,使代码更好吗C++ 具有唯一锁定的并发解析和过滤,c++,multithreading,c++11,concurrency,mutex,C++,Multithreading,C++11,Concurrency,Mutex,我想阅读一个xml文档,过滤我不想要的任何东西(过滤不是问题的一部分),然后写回cout或ofstream 但是,我希望同时执行此操作的方式如下:Thread1(解析器)读取xml文件,一次读取一行(代码中的std::string行),然后将该行提供给thread2,thread2的唯一任务是过滤该行。完成后,它将该行提供回thread1,以写入输出 然而,我现在的程序一点也不安全。首先,有时thread2能够首先获取互斥锁,即使我执行std::unique_lock locker(mu,def
#include <iostream>
#include <string>
#include <fstream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mu;
std::condition_variable cond;
bool checkThread1 = false;
bool checkThread2 = false;
std::string line;
bool checkIfEndOfFile = false;
//std::once_flag flag;
void function1()
{
std::ifstream in("example.xml");
std::unique_lock<std::mutex> locker(mu);
while (getline(in, line))
{
locker.unlock();
cond.notify_one();
checkThread2 = !checkThread2;
cond.wait(locker, []() {return checkThread1; });
}
}
void function2()
{
std::string substring = "";
std::unique_lock<std::mutex> locker(mu);
cond.wait(locker, []() {return checkThread2; });
std::string tmp2 = "";
std::string tmp1;
for (int i = 0; i < line.length(); i++)
{
// Filter
}
locker.unlock();
cond.notify_one();
checkThread1 = !checkThread1;
}
int main()
{
std::thread parser(function1);
std::thread filterer(function2);
parser.join();
filterer.join();
}
#包括
#包括
#包括
#包括
#包括
#包括
std::互斥mu;
std::条件变量cond;
bool-checkThread1=错误;
bool-checkThread2=错误;
std::字符串行;
bool checkIfEndOfFile=false;
//std::once_标志;
无效函数1()
{
std::ifstream in(“example.xml”);
标准:唯一的锁柜(mu);
while(getline(in,line))
{
locker.unlock();
第二,通知某人;
checkThread2=!checkThread2;
cond.wait(locker,[](){return checkThread1;});
}
}
无效函数2()
{
std::string substring=“”;
标准:唯一的锁柜(mu);
cond.wait(locker,[](){return checkThread2;});
std::string tmp2=“”;
std::字符串tmp1;
对于(int i=0;i
可能有人会为您的特定问题提出解决方案,但您的代码没有多大意义。首先,在这里使用线程不会加速任何事情,相反:主线程不做任何事情,其他两个线程必须互相等待——这与只使用一个线程的效果相同。第二:这种问题以前已经解决过,通常是通过线程安全队列解决的。(一个线程将值推送到它上面,另一个线程使用它们)导致代码比您拥有的代码少得多,但更正确(和更有效)。你是对的,它没有优化任何东西,我写这篇文章的目的只是为了教育。你提出了生产者/消费者模型,这就是我要做的。只有一个全局字符串,而不是一个队列。这是完全不同的:一个队列可以容纳多个字符串,但您只有一个字符串。生产者/消费者是典型的情况,生产数据的速度与消费数据的速度不同。因此,队列在那里可以正常工作,只是因为它可以容纳多个字符串。可能有人会为您的特定问题提出解决方案,但您的代码没有多大意义。首先,在这里使用线程不会加速任何事情,相反:主线程不做任何事情,其他两个线程必须互相等待——这与只使用一个线程的效果相同。第二:这种问题以前已经解决过,通常是通过线程安全队列解决的。(一个线程将值推送到它上面,另一个线程使用它们)导致代码比您拥有的代码少得多,但更正确(和更有效)。你是对的,它没有优化任何东西,我写这篇文章的目的只是为了教育。你提出了生产者/消费者模型,这就是我要做的。只有一个全局字符串,而不是一个队列。这是完全不同的:一个队列可以容纳多个字符串,但您只有一个字符串。生产者/消费者是典型的情况,生产数据的速度与消费数据的速度不同。因此,队列在那里工作正常,只是因为它可以容纳多个字符串。