私は、ジョブを消費するコンシューマスレッドの有限集合を持っています。ジョブを処理すると、消費ジョブにリストされたサブジョブのリストが表示されます。私はデータベースにまだ持っていないリストからサブジョブを追加する必要があります。データベースには300万人がいるので、どのデータベースがデータベースにないのかを知るのは遅いです。私は各スレッドがその呼び出しをブロックしても構いませんが、競合状態(コード参照)があるので、遅い呼び出しでそれらをすべてロックする必要があります。したがって、そのセクションを1度に1つしか呼び出しできず、プログラムがクロールします。これを修正するために何をすればスレッドはその呼び出しのために減速しませんか?私はキューを試しましたが、スレッドがコンピュータのリストよりも速くジョブのリストをプッシュしているため、データベースに追加する必要があるものを判断できるため、キューを増やして空にすることはありません。効率的なマルチスレッドセット差へのアプローチ
マイコード:
IEnumerable<string> getUniqueJobNames(IEnumerable<job> subJobs, int setID)
{
return subJobs.Select(el => el.name)
.Except(db.jobs.Where(el => el.set_ID==setID).Select(el => el.name));
}
//...consumer thread i
lock(lockObj)
{
var uniqueJobNames = getUniqueJobNames(consumedJob.subJobs, consumerSetID);
//if there was a context switch here to some thread i+1
// and that thread found uniqueJobs that also were found in thread i
// then there will be multiple copies of the same job added in the database.
// So I put this section in a lock to prevent that.
saveJobsToDatabase(uniqueJobName, consumerSetID);
}
//continue consumer thread i...
何todoをしようとしている、何をやっているのかをもう一度説明することができますが、現在どのように実行しているのかについての情報がなくても、実際の作業はより明確になります。 – ntziolis
先に既存のジョブのリストを取得し、 「新しい」サブジョブを並行して実行し、最後に新しいジョブを保存しますか? –
問題は、例外を使用してデータベースと比較しない限り、新しいものはわかりません。出てくるすべてのサブジョブのリストをコンパイルすることができましたが、最終的にそのリストとデータベースを比較したいとき、次のリストが来るまでに完了しません。それらは、後でリストをキャッシュするか、すぐに実行するかに関係なく、Exceptメソッドを実行するよりも速く構築しています。実際にすぐに実行すると、消費者はより速く実行され、問題は複雑化します。私は、いくつかのデータ構造が役立つかもしれないと推測しています、あるいはちょうど別のアルゴリズムです。 – brandon