、とstdで「タイプ」:: result_ofという名前の無いタイプすべての通信オーバーヘッドを処理するWorkerClientというクラスを介してこれを行います。grpc&いるProtobuf - エラー:<>私は、すべての労働者(grpc非同期サーバ)に作業を配布するマスタークラス(grpc非同期クライアントを)持っている私のプログラムで
私のマスタークラスは、サーバーからの応答を待つためにセットアップする(デタッチ)バックグラウンドスレッドをしよう、と私の困難が生じた場所です。
「AsyncComplete」関数をWorkerClientクラスの一部にしました(grpc.ioのAsync-Greeterチュートリアルに基づく非同期クライアント/サーバーgrpcに関する最近のプログラムのアプローチと同じです)このアプローチのクラスの詳細は以下のとおりです。ここで
class WorkerClient {
public:
WorkerClient(std::shared_ptr<grpc::Channel> channel);
void MapReduceWork(masterworker::WorkReq);
void AsyncComplete(void *, void *, int);
struct AsyncClientCall {
masterworker::WorkReply reply;
grpc::ClientContext context;
grpc::Status status;
std::unique_ptr<grpc::ClientAsyncResponseReader<masterworker::WorkReply>> rsp_reader;
};
std::mutex mtx;
std::unique_ptr<masterworker::MasterWorker::Stub> stub;
grpc::CompletionQueue cq;
masterworker::WorkReq work_req;
ClientState state;
};
class Master {
public:
Master(const MapReduceSpec&, const std::vector<FileShard>&);
......
private:
std::mutex mtx;
std::vector<FileShard> map_tasks;
std::vector<ReduceTask *> reduce_tasks;
std::vector<WorkerClient *> clients;
std::vector<std::string> m_interm_files;
std::vector<FileShard> shards;
MapReduceSpec mr_config;
};
私は、関連する機能が
void WorkerClient::AsyncComplete(void *c, void *m, int client_num)
{
void *got_tag = NULL;
bool ok = false;
Master *mast = static_cast<Master*>(m);
WorkerClient *client = static_cast<WorkerClient*>(c);
cq.Next(&got_tag, &ok);
if (ok == false) {
fprintf(stderr, "cq->Next false!\n");
return;
}
......
}
スレッド
void Master::RunMapJob()
{
// clients[] is of type WorkerClient
ptr = new std::thread(&WorkerClient::AsyncComplete,
static_cast<void*>(clients[i]), static_cast<void*>(this), i);
ptr->detach();
......
}
そして最後に、これまでのところ、問題自体
g++ -c master.cc -I../external/include -std=c++11 -g
In file included from /usr/include/c++/4.8/mutex:42:0,
from master.h:3,
from master.cc:2:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’:
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (WorkerClient::*)(void*, void*, int); _Args = {void*, void*, int&}]’
master.cc:223:65: required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.8/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (WorkerClient::*)(void*, void*, int)>(void*, void*, int)>’
_M_invoke(_Index_tuple<_Indices...>)
^
make: *** [master.o] Error 1
を作成するための呼び出しを詳述しています明らかなものを排除したsは、std :: refを使ってスレッド関数に変数参照を渡すのではなく、一般的には正しいスレッド関数の引数を渡さないようにします。私はAsyncCompleteを静的なスタンドアロンの関数にしようとしましたが、cq.Next(WorkerClient-> cq.Next()に変更)の呼び出しがstd :: bad_alloc例外をスローしていたCompletionQueueコードが舞台裏で行われていることを理解することができます)。
それが助け場合、私は(下記)、コンパイル時に窒息しているようだ/usr/include/c++/4.8/functionalラインを見つけることができた
typedef typename result_of<_Callable(_Args...)>::type result_type;
誰も私がなぜこの両方について説明することができますコンパイルに失敗していて、適切な修正がどのように見えるのでしょうか?私はここに質問を投稿するのが初めてで、フィードバックは大歓迎です。これは長いことを知っていますが、私はすべての情報を持っていることを確認したかったのです。
ありがとうございます。
[システムの詳細:のUbuntu 14.04、3.0 protobufs、protobufs 3.0のソースから構築grpc]
あなたは人生の節約者です...ありがとう!私の以前のプログラムでは、同様のスレッド作成呼び出しを行っていましたが、実際にはバインド呼び出しはありませんでしたが、引き続き引数を渡しました。なぜスレッドctorがバインドを必要とするのか、他のスレッドは必要ないのでしょうか? -----たとえば、--------- スレッド。push_back(新しいstd :: thread(&Vclient :: AsyncComplete、vendors [i]、static_cast(this))); ------------ ここで 'threads'はstd :: threadポインタのベクトルであり、そのコードを含むプログラムは適切にコンパイルされて機能します。 –
user3282129
http://en.cppreference.com/w/cpp/thread/threadの 'std :: thread'文書の例を見ると、最初の引数はファンクタでなければならないことがわかります:' Function && f、Args && ... args'。メソッドのファンクタを作成するには、メソッドをそのクラスのインスタンスにバインドする必要があります。フリースタンディング関数または静的クラスメソッドの場合、バインドする必要はありません。 – jupp0r