在做视频分析时,需要对视频进行解码,还原为位图帧,然后对位图帧逐帧处理。拟用双线程来做。线程A进行解码,线程B进行处理。中间用一个缓冲作为两个线程间通信的渠道。典型的读者写者问题。以前没具体接触过多线程的问题,当年操作系统讲的东西也已经忘的差不多了。翻了翻课本,写出了下面一个实现。
读者写者实现代码
1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Threading;
5![](/Images/OutliningIndicators/None.gif)
6
namespace LearnSemaphore
7![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
8![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
9
/// 封装三个信号量
10
/// </summary>
11
class Signle
12![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
13![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
14
/// Reader和Writer之间的互斥 ,貌似好像可以用Mutex类实现。我这里用的是一个信号量。
15
/// </summary>
16
public Semaphore mutex;
17![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
18
/// 申请写的信号量
19
/// </summary>
20
public Semaphore writer;
21![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
22
/// 申请读的信号量,
23
/// </summary>
24
public Semaphore reader;
25![](/Images/OutliningIndicators/InBlock.gif)
26![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
27
/// Signle的构造函数
28
/// </summary>
29
/// <param name="size">读写缓冲区大小</param>
30
public Signle(int size)
31![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
39
public static void Main(string[] args)
40![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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![](/Images/OutliningIndicators/InBlock.gif)
54![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
55
/// 读者
56
/// </summary>
57
class Reader
58![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
59
//保存信号和缓冲区的引用
60
private Signle signle;
61
private Queue<int> queue;
62![](/Images/OutliningIndicators/InBlock.gif)
63
public Reader(Signle s, Queue<int> que)
64![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
65
signle = s;
66
queue = que;
67
}
68![](/Images/OutliningIndicators/InBlock.gif)
69![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
70
/// 处理函数
71
/// </summary>
72
public void Process()
73![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
74
while (true)
75![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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![](/Images/OutliningIndicators/InBlock.gif)
85![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
86
/// Writer
87
/// </summary>
88
class Writer
89![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
90
private Signle signle;
91
Queue<int> queue;
92![](/Images/OutliningIndicators/InBlock.gif)
93
public Writer(Signle s, Queue<int> que)
94![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
95
signle = s;
96
queue = que;
97
}
98![](/Images/OutliningIndicators/InBlock.gif)
99![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
100
/// 处理函数
101
/// </summary>
102
public void Process()
103![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
104
int ix = 10;
105
while (ix < 100) //测试用的
106
//while (true)
107![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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
}