C++ 两个线程之间的同步队列
这是一个简单的程序,它有一个函数start(),等待用户输入某个内容(使用无限循环)并将其存储在队列中。start()在单独的线程中运行。用户输入某个值后,队列的大小在main中保持为零。如何同步队列?C++ 两个线程之间的同步队列,c++,multithreading,c++11,C++,Multithreading,C++11,这是一个简单的程序,它有一个函数start(),等待用户输入某个内容(使用无限循环)并将其存储在队列中。start()在单独的线程中运行。用户输入某个值后,队列的大小在main中保持为零。如何同步队列? 代码:source.cpp #include <iostream> #include "kl.h" using namespace std; int main() { std::thread t1(start); while (1) { i
代码:source.cpp
#include <iostream>
#include "kl.h"
using namespace std;
int main()
{
std::thread t1(start);
while (1)
{
if (q.size() > 0)
{
std::cout << "never gets inside this if\n";
std::string first = q.front();
q.pop();
}
}
t1.join();
}
#包括
#包括“kl.h”
使用名称空间std;
int main()
{
std::线程t1(开始);
而(1)
{
如果(q.size()>0)
{
std::cout您的代码包含一个-by-me它崩溃了;两个线程都可能在修改共享队列。(另外,您正在使用char i
循环值高达1000-可能不是一个好主意。)
您应该使用保护共享队列,并使用通知有理由检查队列
具体地说,你应该考虑下面的情况(这对于你的情况很常见):
仅在持有互斥锁时访问队列
使用条件变量通知您已将某些内容推入其中
使用condition变量在有点要继续处理时指定一个条件
下面是对您的代码的重写:
#include <iostream>
#include <queue>
#include <thread>
#include <condition_variable>
#include <mutex>
using namespace std;
std::queue<std::string> q;
std::mutex m;
std::condition_variable cv;
void start()
{
string str;
for (std::size_t i = 0; i <= 1000; i++) {
//other stuff and str input
std::cout << "here" << std::endl;
std::unique_lock<std::mutex> lk(m);
q.push(str);
lk.unlock();
cv.notify_one();
}
}
int main()
{
std::thread t1(start);
for (std::size_t i = 0; i <= 1000; i++)
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return !q.empty();});
std::string first = q.front();
q.pop();
}
t1.join();
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
std::队列q;
std::互斥m;
std::条件变量cv;
void start()
{
字符串str;
对于(std::size\u t i=0;i我的同步队列类示例及其用法:
template<typename T>
class SyncQueue
{
std::queue<T> m_Que;
std::mutex m_Lock;
std::condition_variable m_ConVar;
public:
void enque(T item)
{
std::unique_lock<std::mutex> lock(m_Lock);
m_Que.push(item);
lock.unlock();
m_ConVar.notify_all();
}
T deque()
{
std::unique_lock<std::mutex> lock(m_Lock);
do
{
m_ConVar.wait(lock);
} while(m_Que.size() == 0); // extra check from spontaneous notifications
auto ret = m_Que.front();
m_Que.pop();
return ret;
}
};
int main()
{
using namespace std::chrono_literals;
SyncQueue<int> sq;
std::thread consumer([&sq]()
{
std::cout << "consumer" << std::endl;
for(;;)
{
std::cout << sq.deque() << std::endl;
}
});
std::thread provider([&sq]()
{
std::this_thread::sleep_for(1s);
sq.enque(1);
std::this_thread::sleep_for(3s);
sq.enque(2);
std::this_thread::sleep_for(5s);
sq.enque(3);
});
consumer.join();
return 0;
}
模板
类同步队列
{
std::队列m_Que;
std::互斥m_锁;
std::条件变量m_ConVar;
公众:
无效项(T项)
{
std::唯一的_锁锁(m_锁);
m_Que.push(项目);
lock.unlock();
m_ConVar.notify_all();
}
T deque()
{
std::唯一的_锁锁(m_锁);
做
{
m_ConVar.等待(锁定);
}while(m_Que.size()==0);//来自自发通知的额外检查
自动返回=m_Que.front();
m_Que.pop();
返回ret;
}
};
int main()
{
使用名称空间std::chrono_文本;
同步队列;
std::线程使用者([&sq]()
{
std::cout添加了完整的代码因为你在头文件的队列上使用了“static”,实际上你有两个不同的队列,每个cpp文件中都有一个。这就是为什么main文件中的队列总是空的。@tony它显示了删除static时的链接器错误。是的,我怀疑是这样。试试extern。然后在main.cpp中尝试std::queue q;
。h文件显示“这个东西在某处存在”,cpp文件说“它在这里”。更好的是,让它在main中是静态的,从头中删除它,然后通过引用将它传递到线程函数中。@tony谢谢!这个也起作用了
#include <iostream>
#include <queue>
#include <thread>
#include <condition_variable>
#include <mutex>
using namespace std;
std::queue<std::string> q;
std::mutex m;
std::condition_variable cv;
void start()
{
string str;
for (std::size_t i = 0; i <= 1000; i++) {
//other stuff and str input
std::cout << "here" << std::endl;
std::unique_lock<std::mutex> lk(m);
q.push(str);
lk.unlock();
cv.notify_one();
}
}
int main()
{
std::thread t1(start);
for (std::size_t i = 0; i <= 1000; i++)
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return !q.empty();});
std::string first = q.front();
q.pop();
}
t1.join();
}
template<typename T>
class SyncQueue
{
std::queue<T> m_Que;
std::mutex m_Lock;
std::condition_variable m_ConVar;
public:
void enque(T item)
{
std::unique_lock<std::mutex> lock(m_Lock);
m_Que.push(item);
lock.unlock();
m_ConVar.notify_all();
}
T deque()
{
std::unique_lock<std::mutex> lock(m_Lock);
do
{
m_ConVar.wait(lock);
} while(m_Que.size() == 0); // extra check from spontaneous notifications
auto ret = m_Que.front();
m_Que.pop();
return ret;
}
};
int main()
{
using namespace std::chrono_literals;
SyncQueue<int> sq;
std::thread consumer([&sq]()
{
std::cout << "consumer" << std::endl;
for(;;)
{
std::cout << sq.deque() << std::endl;
}
});
std::thread provider([&sq]()
{
std::this_thread::sleep_for(1s);
sq.enque(1);
std::this_thread::sleep_for(3s);
sq.enque(2);
std::this_thread::sleep_for(5s);
sq.enque(3);
});
consumer.join();
return 0;
}