タスク (関数 + パラメーター) を投稿できるスレッド管理クラスを作成しています。クラスはそれらのスレッド化を処理します。
この問題はこのクラス全体にあまり関係していませんが (私が思うに)、複数のスレッドを使用するときに共有リソースをロックするという一般的な問題です。コードは次のとおりです。
メインのテスト ファイル:
#include <iostream>
#include <thread>
#include <vector>
#include "Ttask_1.h"
#include <mutex>
using namespace std;
bool quit=false;
void* square(void* n);
void* print(void* n);
mutex cout_mutex;
mutex res_mutex;
bool cout_locked=false;
vector<Ttask_1<void*,void*>*> tasks1;
vector<Ttask_1<void*,void*>*> tasks2;
void check_for_work(vector<void*> &vec,vector<Ttask_1<void*,void*>*> &tasks)
{
while(!quit)
{
if(tasks.size()!=0)
{
(*tasks[0]).run(vec);
tasks.erase(tasks.begin());
}
else
quit=true;
}
while(cout_locked){}
cout_locked=true;
cout<<"thread done"<<endl;
cout_locked=false;
}
int main(int argc, const char * argv[])
{
vector<void*> vec;
int n=5;
//int *n_p=&n;
//Ttask_1<void*,void*> task(&n,square);
tasks1.push_back(new Ttask_1<void*,void*>(&n,square,true));
tasks1.push_back(new Ttask_1<void*,void*>(&n,print,false));
tasks2.push_back(new Ttask_1<void*,void*>(&n,square,true));
tasks2.push_back(new Ttask_1<void*,void*>(&n,print,false));
thread Thread1(check_for_work,ref(vec),ref(tasks2));
thread Thread2(check_for_work,ref(vec),ref(tasks1));
//(&Ttask_1<int,int>::run,&task,ref(vec));
// task.run(vec,Thread);
Thread1.join();
Thread2.join();
int a;
cin>>a;
return 0;
}
void* print(void* n)
{
for(int i=0;i<*(int*)(n);i++)
{
while(cout_locked){}
cout_locked=true;
cout<<i<<endl;
cout_locked=false;
}
void* a;
return a;
}
void* square(void* n)
{
int res=(*(int*)n)*(*(int*)n);
while(cout_locked){}
cout_locked=true;
cout<<res<<endl;
cout_locked=false;
int *res_p=new int;
res_p=&res;
return res_p;
}
ttask_1 クラス:
#ifndef task_Test_Ttask_1_h
#define task_Test_Ttask_1_h
#include <vector>
#include <mutex>
using namespace std;
extern mutex res_mutex;
template <class type1, class ret>
class Ttask_1
{
public:
Ttask_1(type1 arg_in,ret(*func_p_in)(type1),bool result)
{
safe_result=result;
arg1=arg_in;
func_p=func_p_in;
}
void run(vector<void*> &res_vector)
{
ret res=(*func_p)(arg1);
if(safe_result)
{
void *res_p=&res;
res_mutex.lock();
res_vector.push_back(res_p);
res_mutex.unlock();
}
done=true;
}
bool is_done(){return done;}
private:
bool safe_result;
bool done=false;
type1 arg1;
ret(*func_p)(type1);
};
#endif
ご覧のとおり、ミューテックスが機能していないことを確認した後、cout に独自の「ロック」機能を実装しました。動作はまったく同じなので、これは問題ではありません。
その動作は次のとおりです。
プログラムが終了する前に、数字 0、1、2、3、4、25 と文字列 'thread done' がすべて 2 回出力されることを期待しています。
ただし、非常に頻繁に(常にではありませんが、頻繁に)次の出力が得られます。
25 0 1 2 3 4 スレッド完了 スレッド完了
そのため、いくつかの数字が欠落しており、何が原因なのかわかりません。私が言ったように、私が自分のものを交換するなら
while(cout_locked){}
cout_locked=true;
に
cout_mutex.locked();
と
cout_locked=false;
に
cout_mutex.unlock()
何も変わりません。
助けていただければ幸いです、ありがとう