jjzjj

c++ - std::future.get() 有时卡在 os x 中

coder 2024-02-06 原文

我有两个线程,一个线程应该接收和处理来自另一个线程的请求。第二种是同步传输请求和接收响应。我尝试了以下方案:成对队列(值(value), promise )。第一个线程创建一个 promise 并将其插入同步队列并等待 future.get()

的返回值

问题是有时线程卡在 future.get() 上,但是当我暂停程序执行并继续时它再次正常工作。这个stucks具有随机​​性。

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

我不知道这段代码有什么问题,也许你可以提出更好的解决方案。谢谢

更新

Stucks 只发生在 os x with Apple LLVM version 6.0

在OS X和Linux的gcc下以及Windows的Visual studio下都没有问题

最佳答案

有两个线程,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);

B 与

thread thread(consumer);

你期望 B 先运行,然后卡住,因为

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

B 将继续运行,直到 A 运行以下代码

    cond_.notify_one();

通常会没事的。但是如果A先fun“cond.notify_one()”,B调用“con_.wait(mlock)”,B就会永远卡住。

关于c++ - std::future.get() 有时卡在 os x 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34370995/

有关c++ - std::future.get() 有时卡在 os x 中的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  4. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. ruby - rbenv 安装 ruby​​ 校验和不匹配 osx - 2

    我已经在mountainlion上成功安装了rbenv和ruby​​build。运行rbenvinstall1.9.3-p392结束于:校验和不匹配:ruby-1.9.3-p392.tar.gz(文件已损坏)预期f689a7b61379f83cbbed3c7077d83859,得到1cfc2ff433dbe80f8ff1a9dba2fd5636它正在下载的文件看起来没问题,如果我使用curl手动下载文件,我会得到同样不正确的校验和。有没有人遇到过这个?他们是如何解决的? 最佳答案 tl:博士;使用浏览器从http://ftp.rub

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

    我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

  9. ruby - what is - gets is a directory - 错误信息 - 2

    我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐