DoboWiki
Top
> .NETプログラミング研究/21 をテンプレートにして作成
.NETプログラミング研究/21 をテンプレートにして作成
開始行:
#title(.NETプログラミング研究 第21号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第21号 [#j301c8c2]
**.NET Tips [#s4882f03]
**.NETのマルチスレッドプログラミング その3 [#ec3fd06c]
#column(注意){{
この記事の最新版は「[[.NETのマルチスレッドプログラミング>...
}}
***スレッドの同期 [#e45e9502]
マルチスレッドプログラミングでの難所はスレッドの同期の問...
さらにその中でも同期が必要なケースとして重要でありながら...
はじめに、複数のスレッドが同じオブジェクトにアクセスする...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class [MyClass]
Private count As Integer = 0
Public Sub Increment()
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
'確実に10回以下しか実行されないか?
End If
End Sub
End Class
Class MainClass
'エントリポイント
Public Shared Sub Main()
Dim cls As New [MyClass]
'複数のスレッドを作成し、開始する
Dim i As Integer
For i = 0 To 99
Dim t As New Thread( _
New ThreadStart(AddressOf cls.Increment))
t.Start()
Next i
Console.ReadLine()
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MyClass
{
private int count = 0;
public void Increment()
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
//確実に10回以下しか実行されないか?
}
}
}
class MainClass
{
//エントリポイント
public static void Main()
{
MyClass cls = new MyClass();
//複数のスレッドを作成し、開始する
for (int i = 0; i < 100; i++)
{
Thread t = new Thread(new ThreadStart(cls.Inc...
t.Start();
}
Console.ReadLine();
}
}
}}
上記のプログラムでは、MyClass.Incrementメソッド内の「(何...
実は、十分ありえます。例えばcountの値が9の時、あるスレッ...
このような競合状態を回避するために、スレッドの同期が必要...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class [MyClass]
Private count As Integer = 0
Public Sub Increment()
'ロックを取得
Monitor.Enter(Me)
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
'確実に10回以下しか実行されない
End If
'ロックを開放
Monitor.Exit(Me)
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MyClass
{
private int count = 0;
public void Increment()
{
//ロックを取得
Monitor.Enter(this);
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
//確実に10回以下しか実行されない
}
//ロックを開放
Monitor.Exit(this);
}
}
}}
MyClass.Incrementメソッドの先頭と末尾に
Monitor.Enter(this);
と
Monitor.Exit(this);
を挿入しただけですが、これでこの間のコードブロックには1つ...
Monitor.Enterメソッドは指定されたオブジェクトに対する排他...
Monitorはオブジェクト(参照型)をロックするために使われるた...
-[[Monitor>http://www.microsoft.com/japan/msdn/library/ja...
Monitor.Enterメソッドは複数回呼び出すこともできますが、こ...
(補足:クリティカルセクションはできるだけ短くすべきです...
上記のMonitor.EnterとMonitor.Exitで囲むだけの方法では多少...
先のコードをlockステートメントを使って書き直すと次のよう...
#code(vbnet){{
Class [MyClass]
Private count As Integer = 0
Public Sub Increment()
SyncLock Me
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
End If
End SyncLock
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MyClass
{
private int count = 0;
public void Increment()
{
lock(this)
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
}
}
}
}
}}
静的メソッド内でクリティカルセクションを指定する時は、ロ...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class MainClass
Private Shared count As Integer = 0
'エントリポイント
Public Shared Sub Main()
'複数のスレッドを作成し、開始する
Dim i As Integer
For i = 0 To 99
Dim t As New Thread(New ThreadStart(AddressOf...
t.Start()
Next i
Console.ReadLine()
End Sub
Public Shared Sub MyThread()
SyncLock GetType(MainClass)
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
Console.WriteLine(count)
End If
End SyncLock
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MainClass
{
private static int count = 0;
//エントリポイント
public static void Main()
{
//複数のスレッドを作成し、開始する
for (int i = 0; i < 100; i++)
{
Thread t = new Thread(new ThreadStart(MyThrea...
t.Start();
}
Console.ReadLine();
}
public static void MyThread()
{
lock(typeof(MainClass))
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
Console.WriteLine(count);
}
}
}
}
}}
メソッド全体をクリティカルセクションとするには、MethodImp...
#code(vbnet){{
'Imports System.Threading
'Imports System.Runtime.CompilerServices
'が宣言されているものとする
Class [MyClass]
Private count As Integer = 0
<MethodImpl(MethodImplOptions.Synchronized)> _
Public Sub Increment()
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
Console.WriteLine(count)
End If
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//using System.Runtime.CompilerServices;
//が宣言されているものとする
class MyClass
{
private int count = 0;
[MethodImpl(MethodImplOptions.Synchronized)]
public void Increment()
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
Console.WriteLine(count);
}
}
}
}}
最後に、マルチスレッドプログラミングで「競合状態」ととも...
デッドロックとは、複数のスレッドがお互いにブロックし合い...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class MainClass
Private Shared o1 As New Object
Private Shared o2 As New Object
'エントリポイント
Public Shared Sub Main()
'別スレッドを作成し、開始する
Dim t As New Thread(New ThreadStart(AddressOf MyM...
t.Name = "1"
t.Start()
'o1をロックする
SyncLock o1
Console.WriteLine("メインスレッドでo1をロック")
'しばらく待機
Thread.Sleep(2000)
'o2をロックする
'デッドロックとなる
SyncLock o2
Console.WriteLine("メインスレッドでo2をロ...
End SyncLock
End SyncLock
Console.WriteLine("メインスレッド終了")
End Sub
Private Shared Sub MyMethod()
'しばらく待機
Thread.Sleep(1000)
'o2をロックする
SyncLock o2
Console.WriteLine("スレッド1でo2をロック")
'o1をロックする
'デッドロックとなる
SyncLock o1
Console.WriteLine("スレッド1でo1をロック")
End SyncLock
End SyncLock
Console.WriteLine("スレッド1終了")
End Sub
End Class
}}
#code(csharp){{
private static object o1 = new object();
private static object o2 = new object();
//エントリポイント
public static void Main()
{
//別スレッドを作成し、開始する
Thread t = new Thread(new ThreadStart(MyMethod));
t.Name = "1";
t.Start();
//o1をロックする
lock(o1)
{
Console.WriteLine("メインスレッドでo1をロック");
//しばらく待機
Thread.Sleep(2000);
//o2をロックする
//デッドロックとなる
lock(o2)
{
Console.WriteLine("メインスレッドでo2をロック...
}
}
Console.WriteLine("メインスレッド終了");
}
private static void MyMethod()
{
//しばらく待機
Thread.Sleep(1000);
//o2をロックする
lock(o2)
{
Console.WriteLine("スレッド1でo2をロック");
//o1をロックする
//デッドロックとなる
lock(o1)
{
Console.WriteLine("スレッド1でo1をロック");
}
}
Console.WriteLine("スレッド1終了");
}
}}
上のコードを実行させると、まずメインスレッドでオブジェク...
デッドロックを避けるためには、むやみに同期機構を使わない...
**コメント [#b5d3d8c4]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2003-11-18 (火) 06:00:00,DOB...
終了行:
#title(.NETプログラミング研究 第21号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第21号 [#j301c8c2]
**.NET Tips [#s4882f03]
**.NETのマルチスレッドプログラミング その3 [#ec3fd06c]
#column(注意){{
この記事の最新版は「[[.NETのマルチスレッドプログラミング>...
}}
***スレッドの同期 [#e45e9502]
マルチスレッドプログラミングでの難所はスレッドの同期の問...
さらにその中でも同期が必要なケースとして重要でありながら...
はじめに、複数のスレッドが同じオブジェクトにアクセスする...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class [MyClass]
Private count As Integer = 0
Public Sub Increment()
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
'確実に10回以下しか実行されないか?
End If
End Sub
End Class
Class MainClass
'エントリポイント
Public Shared Sub Main()
Dim cls As New [MyClass]
'複数のスレッドを作成し、開始する
Dim i As Integer
For i = 0 To 99
Dim t As New Thread( _
New ThreadStart(AddressOf cls.Increment))
t.Start()
Next i
Console.ReadLine()
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MyClass
{
private int count = 0;
public void Increment()
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
//確実に10回以下しか実行されないか?
}
}
}
class MainClass
{
//エントリポイント
public static void Main()
{
MyClass cls = new MyClass();
//複数のスレッドを作成し、開始する
for (int i = 0; i < 100; i++)
{
Thread t = new Thread(new ThreadStart(cls.Inc...
t.Start();
}
Console.ReadLine();
}
}
}}
上記のプログラムでは、MyClass.Incrementメソッド内の「(何...
実は、十分ありえます。例えばcountの値が9の時、あるスレッ...
このような競合状態を回避するために、スレッドの同期が必要...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class [MyClass]
Private count As Integer = 0
Public Sub Increment()
'ロックを取得
Monitor.Enter(Me)
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
'確実に10回以下しか実行されない
End If
'ロックを開放
Monitor.Exit(Me)
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MyClass
{
private int count = 0;
public void Increment()
{
//ロックを取得
Monitor.Enter(this);
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
//確実に10回以下しか実行されない
}
//ロックを開放
Monitor.Exit(this);
}
}
}}
MyClass.Incrementメソッドの先頭と末尾に
Monitor.Enter(this);
と
Monitor.Exit(this);
を挿入しただけですが、これでこの間のコードブロックには1つ...
Monitor.Enterメソッドは指定されたオブジェクトに対する排他...
Monitorはオブジェクト(参照型)をロックするために使われるた...
-[[Monitor>http://www.microsoft.com/japan/msdn/library/ja...
Monitor.Enterメソッドは複数回呼び出すこともできますが、こ...
(補足:クリティカルセクションはできるだけ短くすべきです...
上記のMonitor.EnterとMonitor.Exitで囲むだけの方法では多少...
先のコードをlockステートメントを使って書き直すと次のよう...
#code(vbnet){{
Class [MyClass]
Private count As Integer = 0
Public Sub Increment()
SyncLock Me
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
End If
End SyncLock
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MyClass
{
private int count = 0;
public void Increment()
{
lock(this)
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
}
}
}
}
}}
静的メソッド内でクリティカルセクションを指定する時は、ロ...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class MainClass
Private Shared count As Integer = 0
'エントリポイント
Public Shared Sub Main()
'複数のスレッドを作成し、開始する
Dim i As Integer
For i = 0 To 99
Dim t As New Thread(New ThreadStart(AddressOf...
t.Start()
Next i
Console.ReadLine()
End Sub
Public Shared Sub MyThread()
SyncLock GetType(MainClass)
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
Console.WriteLine(count)
End If
End SyncLock
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//が宣言されているものとする
class MainClass
{
private static int count = 0;
//エントリポイント
public static void Main()
{
//複数のスレッドを作成し、開始する
for (int i = 0; i < 100; i++)
{
Thread t = new Thread(new ThreadStart(MyThrea...
t.Start();
}
Console.ReadLine();
}
public static void MyThread()
{
lock(typeof(MainClass))
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
Console.WriteLine(count);
}
}
}
}
}}
メソッド全体をクリティカルセクションとするには、MethodImp...
#code(vbnet){{
'Imports System.Threading
'Imports System.Runtime.CompilerServices
'が宣言されているものとする
Class [MyClass]
Private count As Integer = 0
<MethodImpl(MethodImplOptions.Synchronized)> _
Public Sub Increment()
'countが10より小さい時は1増やす
If count < 10 Then
count += 1
'(何らかの処理)
Console.WriteLine(count)
End If
End Sub
End Class
}}
#code(csharp){{
//using System.Threading;
//using System.Runtime.CompilerServices;
//が宣言されているものとする
class MyClass
{
private int count = 0;
[MethodImpl(MethodImplOptions.Synchronized)]
public void Increment()
{
//countが10より小さい時は1増やす
if (count < 10)
{
count++;
//(何らかの処理)
Console.WriteLine(count);
}
}
}
}}
最後に、マルチスレッドプログラミングで「競合状態」ととも...
デッドロックとは、複数のスレッドがお互いにブロックし合い...
#code(vbnet){{
'Imports System.Threading
'が宣言されているものとする
Class MainClass
Private Shared o1 As New Object
Private Shared o2 As New Object
'エントリポイント
Public Shared Sub Main()
'別スレッドを作成し、開始する
Dim t As New Thread(New ThreadStart(AddressOf MyM...
t.Name = "1"
t.Start()
'o1をロックする
SyncLock o1
Console.WriteLine("メインスレッドでo1をロック")
'しばらく待機
Thread.Sleep(2000)
'o2をロックする
'デッドロックとなる
SyncLock o2
Console.WriteLine("メインスレッドでo2をロ...
End SyncLock
End SyncLock
Console.WriteLine("メインスレッド終了")
End Sub
Private Shared Sub MyMethod()
'しばらく待機
Thread.Sleep(1000)
'o2をロックする
SyncLock o2
Console.WriteLine("スレッド1でo2をロック")
'o1をロックする
'デッドロックとなる
SyncLock o1
Console.WriteLine("スレッド1でo1をロック")
End SyncLock
End SyncLock
Console.WriteLine("スレッド1終了")
End Sub
End Class
}}
#code(csharp){{
private static object o1 = new object();
private static object o2 = new object();
//エントリポイント
public static void Main()
{
//別スレッドを作成し、開始する
Thread t = new Thread(new ThreadStart(MyMethod));
t.Name = "1";
t.Start();
//o1をロックする
lock(o1)
{
Console.WriteLine("メインスレッドでo1をロック");
//しばらく待機
Thread.Sleep(2000);
//o2をロックする
//デッドロックとなる
lock(o2)
{
Console.WriteLine("メインスレッドでo2をロック...
}
}
Console.WriteLine("メインスレッド終了");
}
private static void MyMethod()
{
//しばらく待機
Thread.Sleep(1000);
//o2をロックする
lock(o2)
{
Console.WriteLine("スレッド1でo2をロック");
//o1をロックする
//デッドロックとなる
lock(o1)
{
Console.WriteLine("スレッド1でo1をロック");
}
}
Console.WriteLine("スレッド1終了");
}
}}
上のコードを実行させると、まずメインスレッドでオブジェク...
デッドロックを避けるためには、むやみに同期機構を使わない...
**コメント [#b5d3d8c4]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2003-11-18 (火) 06:00:00,DOB...
ページ名:
▲
▼
[
トップ
] [
新規
|
子ページ作成
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]