簡體   English   中英

std :: future.get()有時會卡在os x中

[英]std::future.get() sometimes stuck in os x

我有兩個線程,一個線程應該接收並處理另一個線程的請求。 第二種是同步傳輸請求和接收響應。 我嘗試了以下方案:對的隊列(值,承諾)。 第一個線程創建一個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

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;
}

我不知道這段代碼有什么問題,也許你可以建議更好的解決方案。 謝謝

UPDATE

只有在帶有Apple LLVM 6.0版的os x中才會出現粘滯現象

在Windows上的OS X和Linux以及Visual Studio上的gcc下沒有問題

有兩個線程,A with

for (int i=0;i<100000;i++){
    int value = mQueue.execute(i);
    cout << "input " << i <<" execute result " <<  value << endl;
}
quit = true;
mQueue.execute(-1);

B帶

thread thread(consumer);

你期望B先跑,然后卡住因為

   while (queue_.empty())
    {
        cond_.wait(mlock);
    }

B將繼續運行,直到A運行以下代碼

    cond_.notify_one();

通常它會沒問題。 但如果A第一個有趣的“cond.notify_one()”,B調用“con_.wait(mlock)”,B將永遠卡住。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM