アクセス数 累計:000,125,039 昨日:000,000,099 本日:000,000,061
|
|
|
|
【Amazon ランキング:ゲーム - キッズ・プレイステーション3】
|
|
スレッド処理において一番怖いのがデットロックです。デットロックを起こすとスレッドがフリーズしてしまうため処理が進まなくなり、最悪アプリケーション全体がフリーズしてしまうような状態に陥る危険性があります。
デットロックはどのような状況で発生するのかというと、左図のように、スレッド1は Obj1 ⇒ Obj2 の順でロックして、スレッド2は Obj2
⇒ Obj1 の順でロックしている場合を想定します。
まずはじめに、スレッド1、スレッド2が同時動いてそれぞれが Obj1, Obj2 をロックします。
スレッド1は次に Obj2 をロックしたいのですが、 すでにスレッド2がロックしているためロック待ち状態になります。一方スレッド2の方も Obj1
をロックしたいのですが、スレッド1にロックされているためこちらもロック待ち状態になってしまいます。
このようにお互いがロックも解除もできない状態になることをデットロックといいます。
この回ではまず、わざとデットロックを起こすプログラムを作成してその仕組みを理解していくことにします。 |
|
デットロックを起こすプログラム |
|
Form4 に Button を2つ貼り付けます。
|
|
VB[Form4.vb] |
Imports System.Threading
Public Class Form4
Private _lockObj1 As Object = New Object()
Private _lockObj2 As Object = New Object()
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles button1.Click
Dim th As Thread = New Thread(AddressOf ThreadProc1)
th.Start()
End Sub
Private Sub button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles button2.Click
Dim th As Thread = New Thread(AddressOf ThreadProc2)
th.Start()
End Sub
' スレッド1処理
Private Sub ThreadProc1()
For i As Integer = 0 To 100
Thread.Sleep(1000)
Console.WriteLine("Proc1:Object1 ロック")
SyncLock (_lockObj1)
Thread.Sleep(1000)
Console.WriteLine("Proc1:Object2 ロック")
SyncLock (_lockObj2)
Thread.Sleep(1000)
End SyncLock
Console.WriteLine("Proc1:Object2 解除")
Thread.Sleep(1000)
End SyncLock
Console.WriteLine("Proc1:Object1 解除")
Next
End Sub
' スレッド2処理
Private Sub ThreadProc2()
For i As Integer = 0 To 100
Thread.Sleep(500)
Console.WriteLine("Proc2:Object2 ロック")
SyncLock (_lockObj2)
Thread.Sleep(500)
Console.WriteLine("Proc2:Object1 ロック")
SyncLock (_lockObj1)
Thread.Sleep(500)
End SyncLock
Console.WriteLine("Proc2:Object1 解除")
Thread.Sleep(500)
End SyncLock
Console.WriteLine("Proc2:Object2 解除")
Next
End Sub
End Class
|
|
C#[Form4.cs] |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadCS
{
public partial class Form4 : Form
{
private object _lockObj1 = new object();
private object _lockObj2 = new object();
public Form4()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread th = new Thread(ThreadProc1);
th.Start();
}
private void button2_Click(object sender, EventArgs e)
{
Thread th = new Thread(ThreadProc2);
th.Start();
}
// スレッド1処理
private void ThreadProc1()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1000);
Console.WriteLine("Proc1:Object1 ロック");
lock (_lockObj1)
{
Thread.Sleep(1000);
Console.WriteLine("Proc1:Object2 ロック");
lock (_lockObj2)
{
Thread.Sleep(1000);
}
Console.WriteLine("Proc1:Object2 解除");
Thread.Sleep(1000);
}
Console.WriteLine("Proc1:Object1 解除");
}
}
// スレッド2処理
private void ThreadProc2()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(500);
Console.WriteLine("Proc2:Object2 ロック");
lock (_lockObj2)
{
Thread.Sleep(500);
Console.WriteLine("Proc2:Object1 ロック");
lock (_lockObj1)
{
Thread.Sleep(500);
}
Console.WriteLine("Proc2:Object1 解除");
Thread.Sleep(500);
}
Console.WriteLine("Proc2:Object2 解除");
}
}
}
}
|
|
実行 |
|
作成したプログラムを実行するにはまず、「スレッド1」ボタンをクリックしてスレッド1を走らせます。その後2、3秒まって「スレッド2」ボタンをクリックしてスレッド2を走らせます。
しばらくはスレッド1、スレッド2とも順番に動いていますがしばらくするとデットロックが発生して処理がフリーズします。
デバッグで出力ウィンドウを表示してロック、解除の状態を確認してください。 |
|
|
※このページで紹介しているサンプルコードについて管理者は動作保障をいたしません※
※サンプルコードを使用する場合は、自己責任でお願いします※
|
【楽天 ランキング:パソコン・周辺機器 - パソコンソフト】
|
|
|
|
このサイトはフリーソフトのMerge HTMLで作成されています。
このサイトはリンクフリーです。
|
ページの先頭に戻る |
Copyright© 2010-2015 Jun.Shiozaki All rights reserved. |
|
|
|