C# 中用信号量实现读者写者问题
在做视频分析时,需要对视频进行解码,还原为位图帧,然后对位图帧逐帧处理。拟用双线程来做。线程A进行解码,线程B进行处理。中间用一个缓冲作为两个线程间通信的渠道。典型的读者写者问题。以前没具体接触过多线程的问题,当年操作系统讲的东西也已经忘的差不多了。翻了翻课本,写出了下面一个实现。
在做视频分析时,需要对视频进行解码,还原为位图帧,然后对位图帧逐帧处理。拟用双线程来做。线程A进行解码,线程B进行处理。中间用一个缓冲作为两个线程间通信的渠道。典型的读者写者问题。以前没具体接触过多线程的问题,当年操作系统讲的东西也已经忘的差不多了。翻了翻课本,写出了下面一个实现。
读者写者实现代码
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Threading;
5
6namespace LearnSemaphore
7{
8 /**//// <summary>
9 /// 封装三个信号量
10 /// </summary>
11 class Signle
12 {
13 /**//// <summary>
14 /// Reader和Writer之间的互斥 ,貌似好像可以用Mutex类实现。我这里用的是一个信号量。
15 /// </summary>
16 public Semaphore mutex;
17 /**//// <summary>
18 /// 申请写的信号量
19 /// </summary>
20 public Semaphore writer;
21 /**//// <summary>
22 /// 申请读的信号量,
23 /// </summary>
24 public Semaphore reader;
25
26 /**//// <summary>
27 /// Signle的构造函数
28 /// </summary>
29 /// <param name="size">读写缓冲区大小</param>
30 public Signle(int size)
31 {
32 mutex = new Semaphore(1, 1);
33 reader = new Semaphore(0, size); //Reader 0个可读
34 writer = new Semaphore(size, size); //Writer size 个可写
35 }
36 }
37 class Program
38 {
39 public static void Main(string[] args)
40 {
41 //信号
42 Signle s = new Signle(10);
43 //数据缓冲区
44 Queue<int> que = new Queue<int>(10);
45
46 //开启一个读者和一个写者线程
47 Thread t1 = new Thread((new Writer(s, que)).Process);
48 Thread t2 = new Thread((new Reader(s, que)).Process);
49 t1.Start();
50 t2.Start();
51 }
52 }
53
54 /**//// <summary>
55 /// 读者
56 /// </summary>
57 class Reader
58 {
59 //保存信号和缓冲区的引用
60 private Signle signle;
61 private Queue<int> queue;
62
63 public Reader(Signle s, Queue<int> que)
64 {
65 signle = s;
66 queue = que;
67 }
68
69 /**//// <summary>
70 /// 处理函数
71 /// </summary>
72 public void Process()
73 {
74 while (true)
75 {
76 signle.reader.WaitOne();
77 signle.mutex.WaitOne();
78 Console.Write("Read:{0} ", queue.Dequeue());
79 signle.mutex.Release();
80 signle.writer.Release();
81 }
82 }
83 }
84
85 /**//// <summary>
86 /// Writer
87 /// </summary>
88 class Writer
89 {
90 private Signle signle;
91 Queue<int> queue;
92
93 public Writer(Signle s, Queue<int> que)
94 {
95 signle = s;
96 queue = que;
97 }
98
99 /**//// <summary>
100 /// 处理函数
101 /// </summary>
102 public void Process()
103 {
104 int ix = 10;
105 while (ix < 100) //测试用的
106 //while (true)
107 {
108 ix++;
109 signle.writer.WaitOne();
110 signle.mutex.WaitOne();
111 Console.Write("Write:{0} ", ix);
112 queue.Enqueue(ix);
113 signle.mutex.Release();
114 signle.reader.Release();
115 }
116 }
117 }
118}
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Threading;
5
6namespace LearnSemaphore
7{
8 /**//// <summary>
9 /// 封装三个信号量
10 /// </summary>
11 class Signle
12 {
13 /**//// <summary>
14 /// Reader和Writer之间的互斥 ,貌似好像可以用Mutex类实现。我这里用的是一个信号量。
15 /// </summary>
16 public Semaphore mutex;
17 /**//// <summary>
18 /// 申请写的信号量
19 /// </summary>
20 public Semaphore writer;
21 /**//// <summary>
22 /// 申请读的信号量,
23 /// </summary>
24 public Semaphore reader;
25
26 /**//// <summary>
27 /// Signle的构造函数
28 /// </summary>
29 /// <param name="size">读写缓冲区大小</param>
30 public Signle(int size)
31 {
32 mutex = new Semaphore(1, 1);
33 reader = new Semaphore(0, size); //Reader 0个可读
34 writer = new Semaphore(size, size); //Writer size 个可写
35 }
36 }
37 class Program
38 {
39 public static void Main(string[] args)
40 {
41 //信号
42 Signle s = new Signle(10);
43 //数据缓冲区
44 Queue<int> que = new Queue<int>(10);
45
46 //开启一个读者和一个写者线程
47 Thread t1 = new Thread((new Writer(s, que)).Process);
48 Thread t2 = new Thread((new Reader(s, que)).Process);
49 t1.Start();
50 t2.Start();
51 }
52 }
53
54 /**//// <summary>
55 /// 读者
56 /// </summary>
57 class Reader
58 {
59 //保存信号和缓冲区的引用
60 private Signle signle;
61 private Queue<int> queue;
62
63 public Reader(Signle s, Queue<int> que)
64 {
65 signle = s;
66 queue = que;
67 }
68
69 /**//// <summary>
70 /// 处理函数
71 /// </summary>
72 public void Process()
73 {
74 while (true)
75 {
76 signle.reader.WaitOne();
77 signle.mutex.WaitOne();
78 Console.Write("Read:{0} ", queue.Dequeue());
79 signle.mutex.Release();
80 signle.writer.Release();
81 }
82 }
83 }
84
85 /**//// <summary>
86 /// Writer
87 /// </summary>
88 class Writer
89 {
90 private Signle signle;
91 Queue<int> queue;
92
93 public Writer(Signle s, Queue<int> que)
94 {
95 signle = s;
96 queue = que;
97 }
98
99 /**//// <summary>
100 /// 处理函数
101 /// </summary>
102 public void Process()
103 {
104 int ix = 10;
105 while (ix < 100) //测试用的
106 //while (true)
107 {
108 ix++;
109 signle.writer.WaitOne();
110 signle.mutex.WaitOne();
111 Console.Write("Write:{0} ", ix);
112 queue.Enqueue(ix);
113 signle.mutex.Release();
114 signle.reader.Release();
115 }
116 }
117 }
118}