c#中的多線程同步

在處理多線程同步問題的時候,我們一般有臨界區,互斥量,信號量和消息機制等幾種解決方案,在c#中可以非常方便的使用它們來實現進程的同步。下面我就常用的lock,Monitor和Mutex幾種來說明如何實現進程的同步。

??? lock和Monitor依靠一種“令牌”對象來實現進程的同步,下面看一段示范代碼:

?

?? class Example
??? {
??????? int count = 0;
??????? object o = new object();//令牌對象
??????? static void Main(string[] args)
??????? {
??????????? Example e=new Example();
??????????? Thread pthread = new Thread(e.produce);
??????????? Thread cthread = new Thread(e.consume);

????????????pthread.Start();

??????????? cthread.Start();

??????? }
??????? public void produce()
??????? {
??????????? while (true)
??????????? {
??????????????? lock (o)
??????????????? {
??????????????????? count = count + 1;
??????????????? }
??????????? }
??????? }
??????? public void consume()
??????? {
??????????? while (true)
??????????? {
??????????????? lock (o)
??????????????? {
??????????????????? count = count - 1;
??????????????? }
??????????? }
??????? }
??? }

??????? 在程序中,我們需要產生兩個生產和消費的線程,但是兩個線程對count的訪問必須是互斥的,也就是要實現兩個現場的同步。在上面的代碼中,首先實例化一個令牌對象o,當需要操作互斥變量count的時候,我就用lock關鍵字去取令牌,如果此時令牌可以拿到,就執行對count的操作,然后釋放令牌。如果此時令牌在另外一個線程手里,就等待知道該令牌被釋放。Monitor的使用與lock很相似,下面附上使用代碼,不再另加說明:

????? Monitor.Enter(o);

????? count=count+1;

????? Monitor.Exit(o);

??????? Mutex是使用互斥的機制來實現進程的同步,Mutex不需要使用額外的令牌對象。下面是用Mutex來解決著名的生產者消費者問題,設定消費者和生產者各3個,公共區容量為5,生產100個,下面看代碼:

???????? class Program
??? {
??????? static void Main(string[] args)
??????? {
??????????? ProduceAndConsume pac=new ProduceAndConsume();
??????????? Thread pthread1 = new Thread(pac.produce);
??????????? Thread pthread2 = new Thread(pac.produce);
??????????? Thread pthread3 = new Thread(pac.produce);
??????????? Thread cthread1 = new Thread(pac.consume);
??????????? Thread cthread2 = new Thread(pac.consume);
??????????? Thread cthread3 = new Thread(pac.consume);
??????????? pthread1.Start();
??????????? pthread2.Start();
??????????? pthread3.Start();
??????????? cthread1.Start();
??????????? cthread2.Start();
??????????? cthread3.Start();
??????? }
??? }
??? class ProduceAndConsume
??? {
??????? private int count = 0;
??????? private int pID=0;
??????? private int cID = 0;
??????? private object mutexobjext = new object();
??????? private Mutex IDmux = new Mutex();//該互斥量是對產品序號的互斥
??????? private Mutex Countmux = new Mutex();//該互斥量是對公共區產品數量的互斥
??????? public void produce()
??????? {
??????????? while (true)
??????????? {
??????????????? IDmux.WaitOne();//申請產品序號互斥,不行則等待
??????????????? if (pID >= 100)
??????????????? {

??????????????????? //達到一百個,釋放互斥,線程結束
??????????????????? IDmux.ReleaseMutex();
??????????????????? break;
??????????????? }
??????????????? Countmux.WaitOne();//申請公共區數量互斥
??????????????? if (count >= 5)
??????????????? {

??????????????????? //公共區滿,生產線程釋放互斥后睡眠
??????????????????? Countmux.ReleaseMutex();
??????????????????? IDmux.ReleaseMutex();
??????????????????? Thread.Sleep(2);
??????????????????? continue;
??????????????? }
??????????????? else
??????????????? {

?????????????????????? //公共區數量加一,并打印生產產品的序號信息,完成后釋放互斥
??????????????????????? count = count + 1;
??????????????????????? Countmux.ReleaseMutex();
??????????????????????? pID = pID + 1;
??????????????????????? Console.WriteLine("Has produced {0}..", pID);
??????????????????????? IDmux.ReleaseMutex();
??????????????????????? Thread.Sleep(1);
??????????????? }
??????????? }
??????? }
??????? public void consume()
??????? {

??????????? //類似于produce(),不同是消費過程
??????????? while (true)
??????????? {
??????????????? IDmux.WaitOne();
??????????????? if(cID>=100)
??????????????? {
??????????????????? IDmux.ReleaseMutex();
??????????????????? break;
??????????????? }
??????????????? Countmux.WaitOne();
??????????????? if (count <= 0)
??????????????? {
??????????????????? Countmux.ReleaseMutex();
??????????????????? IDmux.ReleaseMutex();
??????????????????? Thread.Sleep(2);
??????????????????? continue;
??????????????? }
??????????????? else
??????????????? {
??????????????????????? count = count - 1;
??????????????????????? Countmux.ReleaseMutex();
??????????????????????? cID = cID + 1;
??????????????????????? Console.WriteLine("Has Consume {0}", cID);
??????????????????????? IDmux.ReleaseMutex();
??????????????????????? Thread.Sleep(1);
??????????????? }
??????????? }
??????? }
??? }

????? 下面是執行結果,可以看到進程已經很好的同步了 :

Has produced 1..
Has produced 2..
Has produced 3..
Has produced 4..
Has produced 5..
Has Consume 1
Has produced 6..
Has Consume 2
Has Consume 3
Has Consume 4
Has produced 7..
Has Consume 5
Has Consume 6
Has produced 8..
Has produced 9..
Has Consume 7
Has produced 10..
Has Consume 8
Has Consume 9
Has Consume 10
Has produced 11..
Has produced 12..
Has Consume 11
Has produced 13..
Has produced 14..
Has produced 15..
Has Consume 12
Has produced 16..
Has Consume 13
Has Consume 14
Has produced 17..
Has produced 18..
Has Consume 15
Has produced 19..
Has Consume 16
Has produced 20..
Has Consume 17
Has produced 21..
Has produced 22..
Has Consume 18
Has Consume 19
Has Consume 20
Has produced 23..
Has Consume 21
Has Consume 22
Has produced 24..
Has Consume 23
Has produced 25..
Has produced 26..
Has Consume 24
Has produced 27..
Has Consume 25
Has Consume 26
Has produced 28..
Has Consume 27
Has Consume 28
Has produced 29..
Has produced 30..
Has Consume 29
Has produced 31..
Has Consume 30
Has Consume 31
Has produced 32..
Has Consume 32
Has produced 33..
Has produced 34..
Has produced 35..
..................................

轉載于:https://www.cnblogs.com/yibinboy/archive/2009/12/27/1633077.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379451.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379451.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379451.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ffplay SDL_OpenAudio (2 channels, 44100 Hz): WASAPI can‘t initialize audio client“

windows下&#xff1a; ffplay 提示"SDL_OpenAudio (2 channels, 44100 Hz): WASAPI can’t initialize audio client" 添加環境變量&#xff1a;SDL_AUDIODRIVERdirectsound

js 正則表達式,正整數

var ss "3.333";var type /^[0-9]*[1-9][0-9]*$/;var re new RegExp(type);alert(ss.match(re));if (ss.match(re) null) {alert("請輸入大于零的整數!");return;} 轉載于:https://www.cnblogs.com/lingxzg/archive/2012/08/02/2620543.html

java 根據類名示例化類_Java即時類| EpochSecond()方法的示例

java 根據類名示例化類EpochSecond()方法的即時類 (Instant Class ofEpochSecond() method) Syntax: 句法&#xff1a; public static Instant ofEpochSecond(long sec_val);public static Instant ofEpochSecond(long sec_val, long nanos_adjust);ofEpochSecond() method is…

java中Date()類型輸入數據的處理

對于Date類型的數據&#xff0c;需要輸入生日存入相應數據庫中 private Date birthday;// 生日package com.pdsu.mybatis.pojo;import java.io.Serializable; import java.util.Date;public class User implements Serializable {/*** */private static final long serialVers…

(擴展)歐幾里德快速冪

GCD模板 __int64 gcd(__int64 a,__int64 b) {return b0? a:gcd(b,a%b); } 歐幾里德算法又稱輾轉相除法&#xff0c;用于計算兩個整數a,b的最大公約數。其計算原理依賴于下面的定理&#xff1a; gcd函數就是用來求(a,b)的最大公約數的。 gcd函數的基本性質&#xff1a; gcd(a,…

匯編語言-002(.data、Equal、$、EQU 、MOV 、MOVSX、MOVZX)

1&#xff1a;變量相加程序 .386 .model flat,stdcall.stack 4096 ExitProcess PROTO,dwExitCode:DWORD.data firstval DWORD 20002000h secondval DWORD 11111111h thirdval DWORD 22222222h sum DWORD 0.code main PROCmov eax,firstvaladd eax,secondvaladd eax,thirdvalm…

\r與\n的區別,\r\n與\n或\r的區別(C語言/C#)

本文出處http://topic.csdn.net/t/20020718/07/882679.html 原作者:triout&#xff08;笨牛&#xff09; \r表示回車&#xff0c;\n表示換行&#xff0c;我們按回車按鈕的時候&#xff0c;系統自動產生回車和換行兩個字符&#xff1a; 回車僅僅是表示完成&#xff0c;把光…

通過ID查詢一個用戶的兩種開發方法

通過ID查詢一個用戶的兩種開發方法 數據庫建表sql語句如下&#xff1a;https://github.com/beyondyanyu/Sayingyy/blob/master/JDBC2-數據庫sql建表語句 ①&#xff0c;原始Dao開發&#xff1a; UserDao.java&#xff08;接口&#xff09;: package com.pdsu.mybatis.dao;i…

duration java_Java Duration類| minusMinutes()方法與示例

duration java持續時間類minusMinutes()方法 (Duration Class minusMinutes() method) minusMinutes() method is available in java.time package. minusMinutes()方法在java.time包中可用。 minusMinutes() method is used to subtract the given duration in minutes from t…

Silverlight + WCF異步調用 例子

看大家好像對我的NParsing框架不是很感興趣&#xff08;寫NParsing帖沒人頂我&#xff09;&#xff0c;那就給大家來點“甜品”&#xff0c;換換口謂。來說說Silverlight方面的東西。 在Silverlight中數據通信只能用異步。有人會覺得寫起來很麻煩&#xff0c;其實不然。也有很簡…

我博客主頁的搜索功能怎么不好用

用博客里面的搜索功能&#xff0c;“找找看”&#xff0c;搜索我博客里面的關鍵字&#xff0c;但是不能出現結果。但是我在別人的主頁上能夠搜索該人的內容&#xff0c;能夠查詢到記錄&#xff0c;難道博客園對每個博客的信息要先排序&#xff1f;目前我的還不在他的搜索數據庫…

小議SqlMapConfig.xml配置文件

①、mybatis-3-config.dtd 主要用于mybatis的核心配文件sqlMapConfig.xml的約束 sqlMapConfig.xml代碼如下&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN&q…

ffmepg 命令提取音視頻數據

原文件&#xff1a; 1&#xff1a; 原音頻數據提取&#xff08;保留還是mp4的封裝格式的&#xff09;&#xff1a; ffmpeg -i test_1920x1080.mp4 -acodec copy -vn audio.mp4 -vn 就是沒有視頻&#xff0c; -acodec copy 音頻拷貝不進行任何轉碼 原視頻數據提取&#xff0…

Java BigInteger類| modInverse()方法與示例

BigInteger類modInverse()方法 (BigInteger Class modInverse() method) modInverse() method is available in java.math package. modInverse()方法在java.math包中可用。 modInverse() method is used to calculate the mod inverse by using the inverse of (this BigInteg…

【7】jQuery學習——入門jQuery選擇器之過濾選擇器-可見性過濾選擇器

這篇什么都不說&#xff0c;看標題就知道了&#xff0c;很簡單&#xff0c;就2個選擇器&#xff0c;嘿嘿 選擇器描述返回$("Element:hidden")選取所有不可見的元素集合元素$("Element:visible")選取所有可見元素集合元素這篇很簡單吧&#xff0c;就2個&…

Creating an undraggable TitleWindow container in Flex (轉載)

The following examples show how you can create an undraggable TitleWindow container by setting the isPopUp property to false on the TitleWindow instance. <?xml version"1.0" encoding"utf-8"?><!-- http://blog.flexexamples.com/2…

匯編語言-003(LAHF_SAHF 、XCHG、FLAGS、 OFFSET、ALIGN、PTR、LENGTHOF、SIZEOF)

1&#xff1a;LAHF將EFLAGS符號寄存器低8位字節復制到AH&#xff0c;SAHF將AH復制到EFLAGS符號寄存器低8位字節 .386 .model flat,stdcall.stack 4096 ExitProcess PROTO,dwExitCode:DWORD.data saveflags BYTE ?.code main PROClahfmov saveflags ,ahmov ah,saveflagssahfIN…

Mybatis中的核心配置文件SqlMapConfig.xml詳細介紹

一、properties&#xff08;屬性&#xff09; 可以引用java屬性文件中的配置信息如下 jdbc.properties代碼如下&#xff1a; jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/mybatis?characterEncodingutf-8 jdbc.usernameroot jdbc.passwordbeyond…

用Kotlin開發您的第一個應用程序| Android與Kotlin

In the previous article, we learned how to setup Kotlin in the android studio? Now moving to journey ahead we are going to develop our first app with Kotlin. It is the basic app, but it will let you know the structure of the program. 在上一篇文章中&#x…

數據結構與算法分析-第一章Java類(02)

編寫一個名為Person的類&#xff0c;它包含分別表示人的名字與年齡的兩個數據域。要求此類包含對其中任何一個數據域進行設置與獲取的方法。還要求包含可進行下列測試的方法&#xff1a; 兩個Person對象是否相等--即是否有相同的名稱與年齡一個人是否比另一個人年長 最后&#…