-
09-06-2019 - |
質問
書き込みマルチスレッドの用途には、共通の問題を経験しているレース。
私の質問は、地域:
何人ですか?かを検知ですか。どのような取り扱っています。最後に、どのようにだしている?
解決
レースの状態が二つ以上のスレッドがアクセスできる共有データのみ変更でも同時に行います。このスレッドのスケジューリングアルゴリズムでスワップとスレッドの為、非常に良いのではないかと思いるスレッドにアクセスしようとし共有データです。そのため、結果の変化のデータ依存のスレッドのスケジューリングアルゴリズム、すなわち両方のスレッドは"レース"へのアクセス/変更します。
問題が発生した時のスレッドは、"チェックして法"など"チェック"の場合はX、そして"行動"となることができる価値あるX)、別のスレッドはその値の間に"チェック"や"。例:
if (x == 5) // The "Check"
{
y = x * 2; // The "Act"
// If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
// y will not be equal to 10.
}
点は、yが10んでいれば、それらを受け取ったものかどうかに応じて、別のスレッドを変更xのチェック。いのしようがないわれる。
を防ぐために競合状態から起こるという一般的にクの共有を確保するためのデータのみのスレッドにアクセスできるデータです。このようなこと:
// Obtain lock for x
if (x == 5)
{
y = x * 2; // Now, nothing can change x until the lock is released.
// Therefore y = 10
}
// release lock for x
他のヒント
の"レースの条件"が存在する場合下記からダウンロード(又はその他の並列コードのようにアクセスの共有リソースがないように影響する.
この例:
for ( int i = 0; i < 10000000; i++ )
{
x = x + 1;
}
また5つのスレッドがこの実行コードを一度に、x値になれない50,000,000.うがごとに異なるものが用意されます。
これは、各スレッドの増加は、x値おいしなければならない。(簡易なことは明らかであり)
Retrieve the value of x Add 1 to this value Store this value to x
スレッドで任意のステップこのプロセス時に、これらのステップによりそれぞれ共通の資源てることを計画しています。の状態のxを変更するには別のスレッドの間時間xが読み込まれるときに書いてある。
たとえば、あるスレッドを取得しまxの値が格納されていないられている。別のスレッドでの取得もの 同 xの値がないスレッドを変更しない)そうすることを保存する 同 値(x+1)背中にはx!
例:
Thread 1: reads x, value is 7 Thread 1: add 1 to x, value is now 8 Thread 2: reads x, 値が7 Thread 1: stores 8 in x Thread 2: adds 1 to x, value is now 8 Thread 2: 店舗8x
レースの条件をすることを確認することにより、雇用の ロック メカニズムのコードにアクセスする共有リソース:
for ( int i = 0; i < 10000000; i++ )
{
//lock x
x = x + 1;
//unlock x
}
ここでは、回答が出ると50,000,000ます。
詳ロック、検索:ミューテックス、セマフォ、重要な、共有資源です。
何人ですか?
については、これまでに行き映画5時までです。お問い合わせいただく、チケットは4時までです。の代表ということが可能です。でおくつろぎいただき、チケット窓口に5分前ます。ていらっしゃることだと思いますのでもう:です。問題はこの期間の間にチェック。ご照会での4と5.その間、他の誰かが掴ます。ことになるレースの条件具体的には、"チェックして法"シナリオでのレース。
かを検知ですか。
宗教コード、マルチスレッドユニット。がないストメニューから起動できます。あEclipseプラグイン新興国のことながら安定していない。
どのような取り扱いを防止す。
は、この作成側の効果が無料と無国籍機能を使用immutablesています。がることができない場合があります。そこで、java.util.兼職の状況.原兼職の状況データ構造物の適切な同期、俳優に基づく並行処理でお手伝いいたします。
最高の資源のための並行処理ではJCIP.使用できる必要がありますか。 詳細は上記説明はこちら.
が重要な技術的な違いは競合状態およびデータです。最も回答いくとの前提にこれらの条件と同等のものではない。
データレースが2つの指示にアクセスと同じメモリ位置は、少なくともこれらのアクセスは書き込みありません が起こる前の注文 これからです。今、何が起こる前のご注文はたくさんの議論ものですが、一般的にulockロックペアは、同じロック変数を待-信号ペアは、同じ条件変数の誘導が起こる前ます。
レースの条件である意味エラーになります。で、欠陥が発生する時期や順序のイベントにつながる誤ったプログラム 挙動.
多くのレースの条件(することがありますが、これらによるデータレースでは入力する必要はありません。事実、データのレースとレースの条件は、必要なものに十分条件とします。 この ブログも説明しの違いも、シンプルな銀行取引の一例です。こちらはもう一つの簡単な 例 を説明するには差額をいただきます。
これは釘付けの用語、お答えいただくの質問です。
このレースの条件を意味のバグがないのを検出します。これは、その有する自動oracleを識別することができる正しい対誤ったプログラム動作の一例です。レースの検出が存の問題です。
一方、データ競合的確な定義が必ずしも関わる正確な検出できます。多くの香りのレースデータ検出器(静的-動的データー検出、locksetベースのデータレースの検出が起こる前ベースのデータレースを検出ハイブリッドデータレースを検出).最先端の動的データー検出器 ThreadSanitizer る作品も。
データの取り扱いについてのレース全般に必要とされるグ規律への誘導が起こる前のエッジとアクセスの共有データは開発中には、検出されたのは、上記のツール).ことができるロックスの状態変数に、セマフォなど。しかし、一つでも採用さまざまなプログラミングパラダイムのようなメッセージを渡すには、共有メモリ)を避けるデータレースによる。
種の標準的な定義は"きのスレッドのアクセスの同じ場所にメモリと同時に、少なくとも一つのアクセスは書き込み." のような状況において、"リーダー"のスレッドが、古い価値、新たな価値によっては、スレッドの"勝まで広がることになります。" このはないバグうん毛の低レベルのアルゴリズムをこの目的では一般的に避けてください。@Steve Guryえの良い例ですが、問題です。
レース状態の不具合に起こっているだけ一定の時間的条件です。
例:たとえば二つのスレッドA
スレッド:
if( object.a != 0 )
object.avg = total / object.a
スレッドB
object.a = 0
場合にスレッドはpreemptedかを確認するオブジェクトです。aがnullでない場合、Bい a = 0
, きのスレッドを得のプロセッサまでいくつかに分割によるゼロ"にす
このバグだけれるようにすることがスレッドはpreemptedの直後には、if文では非常に少ないものの、することにもなりかねません。
レースの条件がマルチスレッドの応用やマルチプロセスシステム。レースの条件で最も基本であるものと仮定についても、同じスレッドやプロセスが起きるか、指定した順序で、手順を踏むことになったと言われています。これがスレッドを渡すメッセージの設定-確認のメンバ変数のクラスは両方が機能することが可能です。がほとんど常に競合状態が一つのスレッドで呼眠りに別のスレッドが終了する時間課題(しない限り、睡眠ループでは、チェック機構)。
ツール防止の競合状態に依存しているので、言語やOSがcomonものはミューテックス、そのクリティカルセクション、信号。ミューテックスのきいただくだけで一つであることだ。信号を良くしたいときに必ず誰かが終了しがあることだ。の最小化を共有できる資源を防ぐことも予期せぬ挙動
検出レースでは難しいものがあります。コードに大きく依存してい寝やすいレースの条件で最初にチェックのための通話の影響を受けます。を加え、いよいよ満を持して睡眠にも使用できるデバッグを行う力、特定めます。このために活用できる再生の行動を見て、それができれば消滅による変化の時期のもの、テストソリューションを入れています。の眠を削除後のデバッグしやすくなります。
署名のサインとしてレースの条件がある場合の問題だけを断続的に発生あります。普通のバグがクラッシュとデッドロック.ログ記録、またはあなたの希望する被災地域に戻します。
レースの条件は関連するソフトウェアのものに関連するハードウェアです。実際の期間は当初の新造ハードウェア産業です。
による wikipedia:
の起源の考え方 二つの信号をプレイし へ 影響の出力の最初.
レース条件の論理回路
ソフトウェア産業ではこの期間変更の有無に関わらず、少し分かりにくい。
だけど一部差し替えもにソフトウェアの世界:
- "二つの信号は"=>"二つのスレッド"/"二つのプロセス"
- "影響の出力"=>"共有状態に与えた影響"
では競合状態のソフトウェア産業の"二つのスレッド"/"二つのプロセス"をプレイに与える影響に関する一部の共有状態"の最終結果の共有状態によっても微妙なタイミングの違いによる特定のスレッド/プロセスの起動、スレッド/プロセススケジュール等
レースの状態が状況並行プログラミングが二つの並行スレッドまたはプロセスを競うもので資源の最終状態に依存して誰のための資源です。
Microsoftは、実際に掲載さんの詳細 第 このレースの条件は、デッドロック.最めの抽象からこの項:
レース条件が発生した場合のスレッドがアクセスの共有変数 も同時に行います。最初のスレッドを読み込み変数の スレッドを読み込み、同じ価値を可変となります。その最初のスレッド 次のスレッドを行う業務の値は、レース 事前にご確認くださいスレッドに記述することができる価値の共有に変更します。この値はスレッドに書き込み、その値が保存 このスレッドが執筆に値する前のスレッド たものを書く。
何人ですか?
の状態での過程が重の配列やタイミングのその他のイベント。
例えば、 プロセッサーとプロセッサ億 両方のニーズに対応 同一資源を実行します。
かを検知ですか。
ツールが検出レース状態を自動的に:
どのような取り扱っています。
レース条件を取り扱うことのできる ミューテックス または セマフォ.としてロックできるプロセスを取得する資源に基づく一定の要件防止レースの条件です。
どうでしょうから発?
などの方法があり防止レースの条件など 重要な課回避.
- なプロセスを同時に内重要な地域で(相互排除)
- な前提条件の一つと速度の数のCpuを搭載しています。
- なプロセスの外でその重要な地域であるブロックのその他のプロセス。
- なプロセスにつまでも見送るわけにもいかない入力はその重要な地域です。(待ちB資源億待機資源C,C待機資源)
レースの状態は望ましくない状況時に発生する装置またはシステムの試みを行う二つ以上の作業と同時に、その自然の装置またはシステム本オペレーションズ-リサーチしていただくことが求を適切な順序できます。
コンピュータメモリまたは保管、レース状態にした場合、コマンドを読み書きは大量のデータの受信とほぼ同じ瞬間、機械のみを上書きの一部または全部の古いデータが古いデータが読み出します。結果は、以下のコンピュータクラッシュでは、"不正操作の通知"および停止、プログラムの誤読のデータ誤りに新しいデータです。
ここでは、古典的な銀行口座の残高の例でいる時に初心者かのスレッドJava容易である。r.t.レースの条件
public class BankAccount {
/**
* @param args
*/
int accountNumber;
double accountBalance;
public synchronized boolean Deposit(double amount){
double newAccountBalance=0;
if(amount<=0){
return false;
}
else {
newAccountBalance = accountBalance+amount;
accountBalance=newAccountBalance;
return true;
}
}
public synchronized boolean Withdraw(double amount){
double newAccountBalance=0;
if(amount>accountBalance){
return false;
}
else{
newAccountBalance = accountBalance-amount;
accountBalance=newAccountBalance;
return true;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
BankAccount b = new BankAccount();
b.accountBalance=2000;
System.out.println(b.Withdraw(3000));
}
この記事の基本を理解するためのレース条件:
public class ThreadRaceCondition {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
Account myAccount = new Account(22222222);
// Expected deposit: 250
for (int i = 0; i < 50; i++) {
Transaction t = new Transaction(myAccount,
Transaction.TransactionType.DEPOSIT, 5.00);
t.start();
}
// Expected withdrawal: 50
for (int i = 0; i < 50; i++) {
Transaction t = new Transaction(myAccount,
Transaction.TransactionType.WITHDRAW, 1.00);
t.start();
}
// Temporary sleep to ensure all threads are completed. Don't use in
// realworld :-)
Thread.sleep(1000);
// Expected account balance is 200
System.out.println("Final Account Balance: "
+ myAccount.getAccountBalance());
}
}
class Transaction extends Thread {
public static enum TransactionType {
DEPOSIT(1), WITHDRAW(2);
private int value;
private TransactionType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
};
private TransactionType transactionType;
private Account account;
private double amount;
/*
* If transactionType == 1, deposit else if transactionType == 2 withdraw
*/
public Transaction(Account account, TransactionType transactionType,
double amount) {
this.transactionType = transactionType;
this.account = account;
this.amount = amount;
}
public void run() {
switch (this.transactionType) {
case DEPOSIT:
deposit();
printBalance();
break;
case WITHDRAW:
withdraw();
printBalance();
break;
default:
System.out.println("NOT A VALID TRANSACTION");
}
;
}
public void deposit() {
this.account.deposit(this.amount);
}
public void withdraw() {
this.account.withdraw(amount);
}
public void printBalance() {
System.out.println(Thread.currentThread().getName()
+ " : TransactionType: " + this.transactionType + ", Amount: "
+ this.amount);
System.out.println("Account Balance: "
+ this.account.getAccountBalance());
}
}
class Account {
private int accountNumber;
private double accountBalance;
public int getAccountNumber() {
return accountNumber;
}
public double getAccountBalance() {
return accountBalance;
}
public Account(int accountNumber) {
this.accountNumber = accountNumber;
}
// If this method is not synchronized, you will see race condition on
// Remove syncronized keyword to see race condition
public synchronized boolean deposit(double amount) {
if (amount < 0) {
return false;
} else {
accountBalance = accountBalance + amount;
return true;
}
}
// If this method is not synchronized, you will see race condition on
// Remove syncronized keyword to see race condition
public synchronized boolean withdraw(double amount) {
if (amount > accountBalance) {
return false;
} else {
accountBalance = accountBalance - amount;
return true;
}
}
}
いい捨てレースの条件です。するフラグで読み書きによる複数スレッドは、このフラグの設定を行う"をスレッドすることにより、他のスレッドを停止処理がフラグの設定を行い、したくない"との競合状態に"百万円が含まれております。実際、ここを参照することができて良好なレースの条件です。
しかし、工具を用いて検出のためのレースの条件で発見として有害なレースの条件です。
詳細はレースの条件をここで、 http://msdn.microsoft.com/en-us/magazine/cc546569.aspx.
考えて動作する表示のカウントの数が増加されます。ie., どの CounterThread 単位の値 DisplayThread ニーズを表示最近更新します。
int i = 0;
出力
CounterThread -> i = 1
DisplayThread -> i = 1
CounterThread -> i = 2
CounterThread -> i = 3
CounterThread -> i = 4
DisplayThread -> i = 4
こちらの CounterThread 取得し、ロックが頻繁に更新の前の値 DisplayThread 表示します。ここに存在するレース。レースの条件を解決することができよSynchronzation
ができ 防止のたレースの条件, を使いたい場合、プログラム"機能元素のナノ材料"。その理由は、スレッドにな分離操作の取得および設定例です。
AtomicInteger ai = new AtomicInteger(2);
ai.getAndAdd(5);
その結果、7がリンク"人工知能"。はつの行動が、両方の動作を確認し、同じスレッドやその他のスレッドが干渉することによりレースの条件!
レースの状態は望ましくない状況時に発生する二つ以上の過程でアクセス、変更、共通データも同時に行います。が発生した時があったため、相反するアクセスなります。重要課題の原因となりレースの条件です。解決への重要な条件の中での過程においてのみ一過程であるの実行に重要です。
public class Synchronized_RACECONDITION {
private static final int NUM_INCREMENTS = 10000;
private static int count = 0;
public static void main(String[] args) {
testSyncIncrement();
testNonSyncIncrement();
}
private static void testSyncIncrement() {
count = 0;
ExecutorService executor = Executors.newFixedThreadPool(2);
IntStream.range(0, NUM_INCREMENTS)
.forEach(i -> executor.submit(Synchronized_RACECONDITION::incrementSync));
ConcurrentUtils.stop(executor);
System.out.println(" Sync: " + count);
}
private static void testNonSyncIncrement() {
count = 0;
ExecutorService executor = Executors.newFixedThreadPool(2);
IntStream.range(0, NUM_INCREMENTS)
.forEach(i -> executor.submit(Synchronized_RACECONDITION::increment));
ConcurrentUtils.stop(executor);
System.out.println("NonSync: " + count);
}
private static synchronized void incrementSync() {
count = count + 1;
}
private static void increment() {
count = count + 1;
}
static class ConcurrentUtils {
public static void stop(ExecutorService executor) {
try {
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
System.err.println("termination interrupted");
}
finally {
if (!executor.isTerminated()) {
System.err.println("killing non-finished tasks");
}
executor.shutdownNow();
}
}
}
}