Gek*_*eka 6 c++ macos synchronization future clang
我有两个线程,一个线程应该接收并处理另一个线程的请求.第二种是同步传输请求和接收响应.我尝试了以下方案:对的队列(值,承诺).第一个线程创建一个promise并将其推送到同步队列中并等待返回值future.get()
问题是有时线程卡住future.get(),但当我暂停程序执行并继续它再次正常工作.这种卡住具有随机性.
FutureQueue.h
#ifndef FutureQueue_h
#define FutureQueue_h
#include <queue>
#include <future>
#include <thread>
#include <mutex>
#include <condition_variable>
template <typename T, typename R>
class Work{
public:
Work(){
}
Work(T value, std::promise<R>* promise){
m_value = value;
m_p_promise = promise;
}
std::promise<R>* m_p_promise;
T m_value;
public:
T getValue(){
return m_value;
}
void setResult(R result){
m_p_promise->set_value(result);
}
};
template <typename T, typename R>
class FutureQueue
{
public:
Work<T,R> getWork(){
auto p = pop();
return Work<T,R>(p.first,p.second);
}
R execute(T value)
{
std::promise<R> promise = std::promise<R>();
std::future<R> f = promise.get_future();
auto p = std::pair<T, std::promise<R>*>(value, &promise);
push(p);
return f.get();
}
private:
std::pair<T,std::promise<R>*> pop(){
std::unique_lock<std::mutex> mlock(mutex_);
while (queue_.empty())
{
cond_.wait(mlock);
}
auto item = queue_.front();
queue_.pop();
return item;
}
void push(const std::pair<T,std::promise<R>*>& item){
std::unique_lock<std::mutex> mlock(mutex_);
queue_.push(item);
mlock.unlock();
cond_.notify_one();
}
std::queue<std::pair<T,std::promise<R>*>> queue_;
std::mutex mutex_;
std::condition_variable cond_;
};
#endif
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <iostream>
#include <thread>
#include "FutureQueue.h"
using namespace std;
atomic<bool> quit;
FutureQueue<int, int> mQueue;
void consumer(){
Work<int,int> work;
while(true){
work = mQueue.getWork();
if (quit){
break;
}
int value = work.getValue()+100;
work.setResult(value);
}
work.setResult(0);
}
int main(int argc, const char * argv[]) {
quit = false;
thread thread(consumer);
// test 2
for (int i=0;i<100000;i++){
int value = mQueue.execute(i);
cout << "input " << i <<" execute result " << value << endl;
}
quit = true;
mQueue.execute(-1);
thread.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不知道这段代码有什么问题,也许你可以建议更好的解决方案.谢谢
UPDATE
只有在带有Apple LLVM 6.0版的os x中才会出现粘滞现象
在Windows上的OS X和Linux以及Visual Studio上的gcc下没有问题
小智 0
有两个线程,A 与
for (int i=0;i<100000;i++){
int value = mQueue.execute(i);
cout << "input " << i <<" execute result " << value << endl;
}
quit = true;
mQueue.execute(-1);
Run Code Online (Sandbox Code Playgroud)
乙与
thread thread(consumer);
Run Code Online (Sandbox Code Playgroud)
你期望 B 首先运行,然后卡住,因为
while (queue_.empty())
{
cond_.wait(mlock);
}
Run Code Online (Sandbox Code Playgroud)
B将继续运行直到A运行以下代码
cond_.notify_one();
Run Code Online (Sandbox Code Playgroud)
一般情况下就可以了。但是如果A先调用“cond.notify_one()”,B调用“con_.wait(mlock)”,B将永远卡住。
| 归档时间: |
|
| 查看次数: |
340 次 |
| 最近记录: |