現在、C++を利用してマルチスレッド環境の開発を行っています。
マルチスレッドで排他的に変数を扱う場合、クリティカルセクションや
ミューテックスを使用することで、排他制御をおこなうことができますが、
このように、配列の要素ごとに排他制御を行うことは可能でしょうか?
たとえば、
int ary[10];
のような配列があれば、a[0]~a[9]まで要素をそれぞれ排他制御によって
データの矛盾を避けたいと考えています。
パフォーマンスの関係上、できるだけ、配列全体をロックするのは避けたいと
思っています。
どうぞよろしくお願いします。
No.3
- 回答日時:
こんばんは。
windowsで良ければ、「InterlockedExchange()API」
http://msdn.microsoft.com/ja-jp/library/cc429230 …
を使用するか、配列の個数分クリティカルセクションリソースを用意して、各要素に応じたクリティカルセクションリソースをロックすれば出来ると思います。
アラもあるとは思いますので、以下参考程度に(InterlockedExchangeの方です)。
// consoe.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#define NOMINMAX
#include <windows.h>
#include <process.h>
#include <iostream>
#include <algorithm>
#include <cmath>
static const int NUMARR = 10;
static const int NUMTHREAD = 2;
unsigned WINAPI ThreadA(void* p)
{
LPLONG a = static_cast<LPLONG>(p);
for(int i = 0; i < 12000; ++i)
{
for(int n = 0; n < NUMARR; n += 2)
{
const LONG v = ::InterlockedExchange(&a[n], 0);
::InterlockedExchange(&a[n], v + (std::rand() % 100));
}
::Sleep(0);
}
return 0;
}
unsigned WINAPI ThreadB(void* p)
{
LPLONG a = static_cast<LPLONG>(p);
for(int i = 0; i < 25000; ++i)
{
for(int n = 1; n < NUMARR; n += 2)
{
const LONG v = ::InterlockedExchange(&a[n - 1], 0);
::InterlockedExchange(&a[n - 1], v);
::InterlockedExchange(&a[n], v / std::max(std::rand() % 100, 1));
}
::Sleep(0);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
LONG a[NUMARR] = {0,0,0,0,0,0,0,0,0,0};
HANDLE threads[NUMTHREAD] =
{
reinterpret_cast<HANDLE>(::_beginthreadex(NULL, 0, &::ThreadA, a, 0, NULL)),
reinterpret_cast<HANDLE>(::_beginthreadex(NULL, 0, &::ThreadB, a, 0, NULL)),
};
::WaitForMultipleObjects(NUMTHREAD, threads, TRUE, INFINITE);
for(int i = 0; i < NUMTHREAD; ++i)
::CloseHandle(threads[i]);
for(int i = 0; i < NUMARR; ++i)
std::cout << "a[" << i << "] = " << a[i] << std::endl;
return 0;
}
No.2ベストアンサー
- 回答日時:
マルチスレッド環境での効率的な短時間のin-memory排他的処理は、
次のような形で実現可能です。
H/W命令として cswap: compare and swap 或いは相当の命令がpowerpc,intel他最近の
machineでサポートされているので、それを有効活用します。
http://ja.wikipedia.org/wiki/コンペア・アンド・スワップ
H/W 命令については 例えば "instruction manual cmpxchg intel"でサーチ下さい。
Intel(R) Architecture Software Developer's Manual, Volume 2: Instruction Set Reference Manual
lock-cmpxchg
サブルーチン実装例については google code search でサーチ下さい。
http://www.google.com/codesearch/advanced_code_s …
"compare and swap" lang:c++ etc.
"cmpxchg" lang:assembly etc.
概略の動作は次のような形で実現します。
C++は使っていないので次は擬似コーディングとして参照下さい。
data-blockに関してのlockが必要な場合、int ary[i]相当のlockwordを
data-blockとは別に設けて、そのlockwordにより排他制御を実現します。
data update:
loop:
xold = ary[i];
// generate new data
xnew = xold +delta;
//
xprev = cswapsub(&ary[i],xold,xnew);
if (xprev!=xold) {
// call delay_sub to suppress excessive cswap contention;
// about 500-inst. or 0.5microsec
// (about 10*lock-cmpxchg inst.time ?)
// try to avoid memory store in loop as much as possible
goto loop;
}
...
data reference:
loop:
xold = ary[i];
... data handling// reference
xprev = cswapsub(&ary[i],xold,xold); // check ary[i] data same while processing
if (xprev!=xold) {
// call delay_sub to suppress excessive cswap contention;
// about 500-inst. or 0.5microsec
// try to avoid memory store in loop as much as possible
}
int cswapsub(int* &data, olddata, newdata) {
...
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 教育・文化 高校生です。将来政治家になって犯罪率を0.0%代にしたいのですが、可能だと思いますか? ㅤ 大まかな 8 2022/08/27 18:51
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- 貨物自動車・業務用車両 皆さん、おはようございます。 トラクターのディーゼルエンジンに関するご質問です。 トラクターのディー 2 2022/05/26 05:14
- Ruby 初心者プログラミング 3 2022/10/12 11:31
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- 就職 雇用ビッグバンを起こすべき! 2 2022/04/03 08:58
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
c言語
-
構造体の配列 char *' 型は 'ch...
-
5人分の氏名と英語、国語、数...
-
C言語において、 配列要素をひ...
-
関数から配列を返すには?
-
fclose()でセグメンテーション違反
-
char型配列をint型に代入するには
-
int i, int i[1];
-
C言語の2次元配列 容量が大き...
-
辞書式順序
-
C言語の課題が出たのですが自力...
-
MFC - ダイアログボックスのPic...
-
配列の要素数に変数を入れたい...
-
C言語 ファイルの指定された行...
-
C#で構造体の配列を持った構造...
-
C#でのフィボナッチ数列
-
テキストファイルから文字列を...
-
VBで構造体の配列を関数に渡す...
-
VBAのプログラムで、DIAG = 1# ...
-
セグメントエラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
define で 配列
-
c言語
-
C#で構造体の配列を持った構造...
-
構造体のextern方法
-
C言語において、 配列要素をひ...
-
C#でのフィボナッチ数列
-
C言語の2次元配列 容量が大き...
-
C#で配列が空かを判定するには?
-
配列のアドレス部
-
char型配列をint型に代入するには
-
2番目の最大値を求める
-
C言語の課題が出たのですが自力...
-
C言語についてです 5人のテスト...
-
C言語から質問です。
-
C言語 ファイルの指定された行...
-
c言語 構造体
-
コンボボックスでデフォルト値...
-
MFCのCArrayを使った二次元配列
おすすめ情報