質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

673閲覧

C# 特定のスレッドとの関係でのみ排他制御したい

norinoriko

総合スコア7

排他制御

排他制御とは、特定のファイル・データへのアクセスや更新を制御することです。特にファイルやデータベースへ書き込みを行う際、データの整合性を保つため別のプログラムによる書き込みを一時的に制御することを指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/04/21 09:46

オブジェクトを更新するスレッドとの関係でのみ、オブジェクトをロックするなど排他制御することはできないのでしょうか?

例えば、

  • オブジェクトOを参照するのみの沢山のスレッド群(以下「A群」)
  • 同じオブジェクトOを更新するスレッド(以下「B」)

があった場合に
OをA群の間では排他制御を行わず、A群とBとの間では排他制御するようなことはできないのでしょうか?
よろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BluOxy

2019/04/21 09:49

>オブジェクトを更新するスレッドとの関係でのみ、オブジェクトをロックするなど排他制御すること そのような実装をしたい背景を追記していただけると幸いです。
BluOxy

2019/04/21 10:14

文章をよく理解できていませんでした。失礼しました。 更新だけ排他を取りたいケースはザラにありましたね。
guest

回答2

0

ベストアンサー

ReaderWriterLockSlimクラスはどうでしょう?

単純なサンプルです

C#

1using System; 2using System.Threading.Tasks; 3using System.Threading; 4 5 6namespace ConsoleApp1 7{ 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 13 readthread1(); 14 readthread2(); 15 writethread(); 16 17 Console.ReadKey(); 18 } 19 20 static ReaderWriterLockSlim lockslim = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); 21 22 static void readthread1() 23 { 24 Task.Run(() => 25 { 26 while (true) 27 { 28 lockslim.EnterReadLock(); 29 Console.WriteLine("Read Thread1 実行開始"); 30 31 Thread.Sleep(100); 32 33 Console.WriteLine("Read Thread1 実行終了"); 34 lockslim.ExitReadLock(); 35 36 Thread.Sleep(200); 37 } 38 }); 39 } 40 41 42 static void readthread2() 43 { 44 Task.Run(() => 45 { 46 while (true) 47 { 48 lockslim.EnterReadLock(); 49 Console.WriteLine("Read Thread2 実行開始"); 50 51 Thread.Sleep(200); 52 53 Console.WriteLine("Read Thread2 実行終了"); 54 lockslim.ExitReadLock(); 55 56 Thread.Sleep(300); 57 } 58 }); 59 } 60 61 62 static void writethread() 63 { 64 Task.Run(() => 65 { 66 while (true) 67 { 68 lockslim.EnterWriteLock(); 69 Console.WriteLine("Write Thread 実行開始"); 70 71 Thread.Sleep(2000); 72 73 Console.WriteLine("Write Thread 実行終了"); 74 lockslim.ExitWriteLock(); 75 76 Thread.Sleep(300); 77 } 78 }); 79 } 80 } 81} 82

このような感じに出力されます。

Read Thread1 実行開始 Read Thread2 実行開始 Read Thread1 実行終了 Read Thread2 実行終了 Write Thread 実行開始 Write Thread 実行終了 Read Thread2 実行開始 Read Thread1 実行開始 Read Thread1 実行終了 Read Thread2 実行終了 Read Thread1 実行開始 Read Thread1 実行終了 Write Thread 実行開始 Write Thread 実行終了 Read Thread2 実行開始 Read Thread1 実行開始 Read Thread1 実行終了 Read Thread2 実行終了 Read Thread1 実行開始 Read Thread1 実行終了 Write Thread 実行開始 Write Thread 実行終了 Read Thread2 実行開始 Read Thread1 実行開始 Read Thread1 実行終了

投稿2019/04/21 10:06

編集2019/04/21 11:10
YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

norinoriko

2019/04/22 09:29

ありがとうございます 欲しかったのこれです、バッチリでした
YAmaGNZ

2019/04/22 09:46

サンプルでは書いてありませんが、ロックしたまま処理を抜けるような構造に注意してください。 ロック後、try~finally等でロック解除を確実に行わないと、デッドロックになったりします。
guest

0

AとBの間だけでLock、Unlockすればいいんでは


Aはたくさんのスレッド、なんですね
その個数が決まってるなら、その個数分のオブジェクトを作ってlock-unlockして、Bはそのすべてのオブジェクトでlockする、ってことぐらい?

#ちと現実的やないですわな

投稿2019/04/21 10:10

編集2019/04/21 10:22
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問