线程同步及线程用到的锁对象

转载 2012年03月23日 13:44:20

转自:http://blog.csdn.net/ghostbear/article/details/7328686

 

如果程序涉及到多个线程协同完成某项任务,那么你将会面对线程同步的问题。.Net为这类为题提供了很好的解决方案,我们只需要书写少量的代码就能避免线程出现死锁。

线程同步

辅助类  

  1. class ThreadSync 
  2.  
  3.     { 
  4.  
  5.         public long data1; 
  6.  
  7.         public long data2; 
  8.  
  9.   
  10.  
  11.         public void Increase() 
  12.  
  13.         { 
  14.  
  15.             data2++; 
  16.  
  17.         } 
  18.  
  19.  
  20.   
  21.  
  22.     class AlgorithmicTimer 
  23.  
  24.     { 
  25.  
  26.         public DateTime startTime { get; set; } 
  27.  
  28.         public DateTime endTime { get; set; } 
  29.  
  30.   
  31.  
  32.         public void Analyse() 
  33.  
  34.         { 
  35.  
  36.             Console.WriteLine( 
  37.  
  38. string.Format("当前程序共运行了:{0}秒" 
  39.  
  40. , (endTime - startTime).TotalSeconds)); 
  41.  
  42.         } 
  43.  
  44.   
  45.  
  46.   
  47.  
  48.     } 
  49.  


调用代码

  1. ThreadSync myThreadSync = new ThreadSync(); 
  2.  
  3. AlgorithmicTimer timer = new AlgorithmicTimer(); 
  4.  
  5.              
  6.  
  7.     timer.startTime = DateTime.Now; 
  8.  
  9.     for (int i = 0; i < 100000000; i++) 
  10.  
  11.     { 
  12.  
  13.         myThreadSync.Increase(); 
  14.  
  15.  
  16.   
  17.  
  18.     Console.WriteLine(myThreadSync.data2); 
  19.  
  20.     timer.endTime = DateTime.Now; 
  21.  
  22.     timer.Analyse(); 
  23.  
  24.              
  25.  
  26.     myThreadSync.data2 = 0; 
  27.  
  28.     timer.startTime = DateTime.Now; 
  29.  
  30.     Parallel.For(0, 100000000, (index) => 
  31.  
  32.     { 
  33.  
  34.         lock (myThreadSync)  //不加上Lock得到的结果不正确 
  35.  
  36.         { 
  37.  
  38.             myThreadSync.Increase(); 
  39.  
  40.         } 
  41.  
  42. }); 
  43.  
  44.   
  45.  
  46.     Console.WriteLine(myThreadSync.data2); 
  47.  
  48.     timer.endTime = DateTime.Now; 
  49.  
  50.     timer.Analyse(); 


执行结果

 

100000000

当前程序共运行了:1.1740671秒

100000000

当前程序共运行了:11.4436546秒

PV信号量操作

  1. //Semaphore 信号量对象,PV 操作 
  2.  
  3. int threadCount = 6; 
  4.  
  5. int semaphoreCount = 4; 
  6.  
  7. var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount); 
  8.  
  9. var threads = new Thread[threadCount]; 
  10.  
  11.  
  12.  
  13. for (int i = 0; i < threadCount; i++) 
  14.  
  15.  
  16.      threads[i] = new Thread(mysemaphore.ThreadMain); 
  17.  
  18.      threads[i].Start(semaphore); 
  19.  
  20.  
  21.  
  22.  
  23. for (int i = 0; i < threadCount; i++) 
  24.  
  25.  
  26.      threads[i].Join(); 
  27.  
  28.  
  29. Console.WriteLine("All threads finished!"); 


Mysemaphore类型

  1. using System; 
  2.  
  3. using System.Collections.Generic; 
  4.  
  5. using System.Linq; 
  6.  
  7. using System.Text; 
  8.  
  9.   
  10.  
  11. using System.Threading; 
  12.  
  13. using System.Threading.Tasks; 
  14.  
  15. using System.Diagnostics; 
  16.  
  17.   
  18.  
  19. namespace chapter20 
  20.  
  21.  
  22.     class mysemaphore 
  23.  
  24.     { 
  25.  
  26.         public static  void ThreadMain(object o) 
  27.  
  28.         { 
  29.  
  30.             SemaphoreSlim semaphore = o as SemaphoreSlim; 
  31.  
  32.             Trace.Assert(semaphore != null, "o must be a Semaphore type"); 
  33.  
  34.             bool isCompleted = false
  35.  
  36.             while (!isCompleted) 
  37.  
  38.             { 
  39.  
  40.                 if (semaphore.Wait(600)) 
  41.  
  42.                 { 
  43.  
  44.                     try 
  45.  
  46.                     { 
  47.  
  48.                         Console.WriteLine("Thread {0} locks the semaphore 
  49.  
  50. ,Current PV:{1}" 
  51.  
  52. , new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount}); 
  53.  
  54.                         
  55.  
  56.                         Thread.Sleep(2000); 
  57.  
  58.                     } 
  59.  
  60.                     finally 
  61.  
  62.                     { 
  63.  
  64.                         semaphore.Release(); 
  65.  
  66.                         Console.WriteLine("Thread {0} release the semaphore,Current PV:{1}", new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount}); 
  67.  
  68.                       
  69.  
  70.                         isCompleted = true
  71.  
  72.                     } 
  73.  
  74.                 } 
  75.  
  76.                 else 
  77.  
  78.                 { 
  79.  
  80.                     Console.WriteLine("Timeout for thread {0},wait again", Thread.CurrentThread.ManagedThreadId); 
  81.  
  82.                 } 
  83.  
  84.             } 
  85.  
  86.         } 
  87.  
  88.     } 
  89.  


执行结果:

 

Thread 9 locks the semaphore,Current PV:3

Thread 10 locks the semaphore,Current PV:2

Thread 11 locks the semaphore,Current PV:1

Thread 12 locks the semaphore,Current PV:0

Timeout for thread 13,wait again

Timeout for thread 14,wait again

Timeout for thread 13,wait again

Timeout for thread 14,wait again

Thread 9 release the semaphore,Current PV:1

Thread 13 locks the semaphore,Current PV:0

Thread 11 release the semaphore,Current PV:2

Timeout for thread 14,wait again

Thread 10 release the semaphore,Current PV:1

Thread 14 locks the semaphore,Current PV:2

Thread 12 release the semaphore,Current PV:3

Thread 13 release the semaphore,Current PV:3

Thread 14 release the semaphore,Current PV:4

All threads finished!

Event类

    解决资源分配问题,当程序释放资源时改变该事件的状态。通知其他程序它释放了资源。

辅助类

   

  1. class Calculator 
  2.  
  3.     { 
  4.  
  5.         private ManualResetEventSlim mEvent; 
  6.  
  7.         public int Result { get; private set; } 
  8.  
  9.         public Calculator(ManualResetEventSlim ev) 
  10.  
  11.         { 
  12.  
  13.             this.mEvent = ev; 
  14.  
  15.         } 
  16.  
  17.   
  18.  
  19.         public void Calculation(object obj) 
  20.  
  21.         { 
  22.  
  23.             Tuple<int, int> data = obj as Tuple<int, int>; 
  24.  
  25.             Console.WriteLine("Task {0} starts calculation" 
  26.  
  27. , Task.CurrentId); 
  28.  
  29.             Thread.Sleep(new Random().Next(3000)); 
  30.  
  31.             Result = data.Item1 + data.Item2; 
  32.  
  33.   
  34.  
  35.             Console.WriteLine("Task {0} is ready", Task.CurrentId); 
  36.  
  37.             mEvent.Set(); 
  38.  
  39.         } 
  40.  
  41.  
  42.   


调用代码:

  

  1. //Event 类 
  2.  
  3.    int taskCount = 4; 
  4.  
  5.    var mEvents = new ManualResetEventSlim[taskCount]; 
  6.  
  7.    var waitHandles = new WaitHandle[taskCount]; 
  8.  
  9.    var calcs = new Calculator[taskCount]; 
  10.  
  11.  
  12.  
  13.    TaskFactory taskFactory = new TaskFactory(); 
  14.  
  15.    for (int i = 0; i < taskCount; i++) 
  16.  
  17.    { 
  18.  
  19.        mEvents[i] = new ManualResetEventSlim(false); 
  20.  
  21.        waitHandles[i] = mEvents[i].WaitHandle; 
  22.  
  23.        calcs[i] = new Calculator(mEvents[i]); 
  24.  
  25.  
  26.  
  27.        taskFactory.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3)); 
  28.  
  29.  
  30.  
  31.    } 
  32.  
  33.  
  34.  
  35.    for (int i = 0; i < taskCount; i++) 
  36.  
  37.    { 
  38.  
  39.        int index = WaitHandle.WaitAny(waitHandles); 
  40.  
  41.        if (index == WaitHandle.WaitTimeout) 
  42.  
  43.        { 
  44.  
  45.            Console.WriteLine("Timeout!!"); 
  46.  
  47.        } 
  48.  
  49.        else 
  50.  
  51.        { 
  52.  
  53.            mEvents[index].Reset(); 
  54.  
  55.            Console.WriteLine("finished task for {0},result:{1}", index, calcs[index].Result); 
  56.  
  57.        } 
  58.  
  59.  
  60.  
  61.    } 


执行结果:

 

Task 1 starts calculation

Task 3 starts calculation

Task 2 starts calculation

Task 4 starts calculation

Task 2 is ready

Task 3 is ready

Task 4 is ready

finished task for 1,result:6

finished task for 2,result:8

finished task for 3,result:10

Task 1 is ready

finished task for 0,result:4

ReadWriterLockSlim(同步资源的读写)

    呵呵,额对这个东西的产生表示很无解。

 

  1. class MyReadWriterLockSlim 
  2.  
  3.   { 
  4.  
  5.       private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 }; 
  6.  
  7.       private static ReaderWriterLockSlim rwl = new 
  8.  
  9.             ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); 
  10.  
  11.  
  12.  
  13.      public static void ReaderMethod(object reader) 
  14.  
  15.       { 
  16.  
  17.           try 
  18.  
  19.           { 
  20.  
  21.               rwl.EnterReadLock(); 
  22.  
  23.  
  24.  
  25.               for (int i = 0; i < items.Count; i++) 
  26.  
  27.               { 
  28.  
  29.                   Console.WriteLine("reader {0}, loop: {1}, item: {2}"
  30.  
  31.                         reader, i, items[i]); 
  32.  
  33.                   Thread.Sleep(40); 
  34.  
  35.               } 
  36.  
  37.           } 
  38.  
  39.           finally 
  40.  
  41.           { 
  42.  
  43.               rwl.ExitReadLock(); 
  44.  
  45.           } 
  46.  
  47.       } 
  48.  
  49.  
  50.  
  51.      public static void WriterMethod(object writer) 
  52.  
  53.       { 
  54.  
  55.           try 
  56.  
  57.           { 
  58.  
  59.               while (!rwl.TryEnterWriteLock(50)) 
  60.  
  61.               { 
  62.  
  63.                   Console.WriteLine("Writer {0} waiting for the write lock"
  64.  
  65.                         writer); 
  66.  
  67.                   Console.WriteLine("current reader count: {0}"
  68.  
  69.                         rwl.CurrentReadCount); 
  70.  
  71.               } 
  72.  
  73.               Console.WriteLine("Writer {0} acquired the lock", writer); 
  74.  
  75.               for (int i = 0; i < items.Count; i++) 
  76.  
  77.               { 
  78.  
  79.                   items[i]++; 
  80.  
  81.                   Thread.Sleep(50); 
  82.  
  83.               } 
  84.  
  85.               Console.WriteLine("Writer {0} finished", writer); 
  86.  
  87.           } 
  88.  
  89.           finally 
  90.  
  91.           { 
  92.  
  93.               rwl.ExitWriteLock(); 
  94.  
  95.           } 
  96.  
  97.       } 
  98.  
  99.  
  100.  
  101.      public static void Go() 
  102.  
  103.       { 
  104.  
  105.           var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None); 
  106.  
  107.           var tasks = new Task[6]; 
  108.  
  109.           tasks[0] = taskFactory.StartNew(WriterMethod, 1); 
  110.  
  111.           tasks[1] = taskFactory.StartNew(ReaderMethod, 1); 
  112.  
  113.           tasks[2] = taskFactory.StartNew(ReaderMethod, 2); 
  114.  
  115.           tasks[3] = taskFactory.StartNew(WriterMethod, 2); 
  116.  
  117.           tasks[4] = taskFactory.StartNew(ReaderMethod, 3); 
  118.  
  119.           tasks[5] = taskFactory.StartNew(ReaderMethod, 4); 
  120.  
  121.  
  122.  
  123.           for (int i = 0; i < 6; i++) 
  124.  
  125.           { 
  126.  
  127.               tasks[i].Wait(); 
  128.  
  129.           } 
  130.  
  131.       } 
  132.  
  133.   } 


执行结果:

 

reader 1, loop: 0, item: 0

reader 1, loop: 1, item: 1

reader 3, loop: 0, item: 0

Writer 1 waiting for the write lock

current reader count: 3

reader 4, loop: 0, item: 0

Writer 2 waiting for the write lock

reader 1, loop: 2, item: 2

reader 3, loop: 1, item: 1

current reader count: 3

reader 4, loop: 1, item: 1

reader 3, loop: 2, item: 2

reader 1, loop: 3, item: 3

reader 4, loop: 2, item: 2

Writer 1 waiting for the write lock

reader 3, loop: 3, item: 3

current reader count: 3

Writer 2 waiting for the write lock

reader 1, loop: 4, item: 4

reader 3, loop: 4, item: 4

reader 4, loop: 3, item: 3

current reader count: 3

Writer 1 waiting for the write lock

current reader count: 3

reader 3, loop: 5, item: 5

reader 1, loop: 5, item: 5

reader 4, loop: 4, item: 4

reader 4, loop: 5, item: 5

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

current reader count: 1

reader 2, loop: 0, item: 0

current reader count: 1

reader 2, loop: 1, item: 1

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

reader 2, loop: 2, item: 2

current reader count: 1

current reader count: 1

reader 2, loop: 3, item: 3

Writer 1 waiting for the write lock

Writer 2 waiting for the write lock

reader 2, loop: 4, item: 4

current reader count: 1

current reader count: 1

reader 2, loop: 5, item: 5

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

current reader count: 0

current reader count: 0

Writer 1 acquired the lock

Writer 2 waiting for the write lock

current reader count: 0

Writer 2 waiting for the write lock

current reader count: 0

Writer 2 waiting for the write lock

current reader count: 0

Writer 1 finished

Writer 2 acquired the lock

Writer 2 finished

 

相关文章推荐

C#中的线程同步及线程用到的锁对象

线程同步及线程用到的锁对象    如果程序涉及到多个线程协同完成某项任务,那么你将会面对线程同步的问题。.Net为这类为题提供了很好的解决方案,我们只需要书写少量的代码就能避免线程出现死锁。线程同步辅...

进程与线程(六)用内核对象进行线程同步(下)

信号量,资源计数为0时未触发,计数大于0时触发,现在看这个例子可能不会觉得有什么用,等到多线程这块结束时拿出一个我高二时写的多线程的例子~就会看出其用处了~暂且无聊一下~ 1 int _tmai...

IOS线程管理,线程同步

  • 2012年07月20日 07:18
  • 897KB
  • 下载

64 互斥锁 线程通信 线程同步

1>互斥锁:互斥锁使用格式 @synchronized(锁对象) { // 需要锁定的代码 } 注意:锁定1份代码只用1把锁,用多把锁是无效的互斥锁的优缺点 优点:能有效防止因多线程抢夺资源造成的数...

线程控制[pthread_create() pthread_join()] 线程同步[互斥锁 条件变量 信号量]

x86/Debian Linux/gcc 2 线程控制 此笔记涉及的线程库函数是由POSIX标准定义的,称为POSIXthread或者pthread。其它也有很多关于线程的库如C++ Boost的...

Linux C 信号、线程同步、线程互斥锁、线程条件变量

这一周学习 信号处理,线程pthread的创建、同步、阻塞、激发的情形信号量的处理函数#include "func.h" void sig(int signum) { // 同一个信号量最多执行两遍 ...

Linux线程编程 - 线程同步机制之互斥锁

互斥锁基本原理 互斥以排他方式防止共享数据被并发修改。互斥锁是一个二元变量,其状态为开锁(允许0)和上锁(禁止1),将某个共享资源与某个特定互斥锁绑定后,对该共享资源的访问如下操作: (1)在访问该...

初学线程纠结ing--线程同步与锁

线程的同步与锁一、同步问题提出线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。例如:两个线程ThreadA、ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据。pub...

java线程(4)——线程同步的锁技术

同步 同步,字面来看,有点一起工作的意思。但在线程同步中,“同”意为协同、互相配合。 比如:A、B两个线程,并不是说两个线程必须同时一起工作,而是说互相配合工作,在某个时间可能线程A要等线程B去工...

多线程--线程同步、死锁、守护线程、多线程下载

1 线程同步 当两个或多个线程需要访问同一资源时,需要确保该资源某一时刻只能被一个线程使用 1.1同步代码块 同步代码块:synchronized放在对象前面限制一段代码的执行 synchronize...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:线程同步及线程用到的锁对象
举报原因:
原因补充:

(最多只允许输入30个字)