多线程读写文件一直是一个比较常用的技术,普通的锁显得效率低下,和单线程感觉基本没有啥区别,这里参考了大牛的代码,采用了线程池技术,小菜我一直不明白异步和多线程有啥区别,后来读了个大牛的博客,才明白,为加强理解,抄袭一下吧,
多线程相关名词概念的解释
并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。
其中两种并发关系分别是同步和互斥
- 互斥:进程间相互排斥的使用临界资源的现象,就叫互斥。
- 同步:进程之间的关系不是相互排斥临界资源的关系,而是相互依赖的关系。进一步的说明:就是前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。具有同步关系的一组并发进程相互发送的信息称为消息或事件。
其中并发又有伪并发和真并发,伪并发是指单核处理器的并发,真并发是指多核处理器的并发。
并行:在单处理器中多道程序设计系统中,进程被交替执行,表现出一种并发的外部特种;在多处理器系统中,进程不仅可以交替执行,而且可以重叠执行。在多处理器上的程序才可实现并行处理。从而可知,并行是针对多处理器而言的。并行是同时发生的多个并发事件,具有并发的含义,但并发不一定并行,也亦是说并发事件之间不一定要同一时刻发生。
异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事情。实现异步可以采用多线程技术或则交给另外的进程来处理。
如果都是独占cpu 的业务, 比如举杠铃的业务, 在单核情况下 多线和单线 没有区别。
总结
- 多线程的好处:比较容易的实现了异步切换的思想,
- 多线程本身程还是以同步完成,但是应该说比效率是比不上异步的。
- 多核的好处,就是可以同时做事情, 这个和单核完全不一样的。
线程池异步读写文件
废话不说了,直接上代码,很好理解的
- 1
class Program
{
static void Main(string[] args)
{
//把线程池的最大值设置为1000
ThreadPool.SetMaxThreads(1000, 1000);
ThreadPoolMessage("Start");
#region 异步写文件
//新立文件temp.txt
FileStream stream0 = new FileStream("temp.txt", FileMode.OpenOrCreate,FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
byte[] bytes = new byte[16384];
string message = "An operating-system ThreadId...";
bytes = Encoding.Unicode.GetBytes(message);
//启动异步写入
stream0.BeginWrite(bytes, 0, (int)bytes.Length, new AsyncCallback(CallbackWrite), stream0);
stream0.Flush();
#endregion
//----------------------------------------------------
#region 异步读文件
byte[] byteData = new byte[80961024];
FileStream stream1 = new FileStream("temp.txt", FileMode.OpenOrCreate,FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
/*把FileStream对象,byte[]对象, 长度等有关数据绑定到FileData对象中, 以附带属性方式送到回调函数 */
FileData fileData = new FileData();
fileData.Stream = stream1;
fileData.Length = (int)stream1.Length;
fileData.ByteData = byteData;
//启动异步读取
stream1.BeginRead(byteData, 0, fileData.Length, new AsyncCallback(CallbackRead), fileData);
#endregion
Console.ReadKey();
}
/// <summary>
/// 写文件的回调函数
/// </summary>
/// <param name="result"></param>
static void CallbackWrite(IAsyncResult result)
{
//显示线程池现状
Thread.Sleep(200);
ThreadPoolMessage("CallbackWrite");
//结束异步写入
FileStream stream = (FileStream)result.AsyncState;
stream.EndWrite(result);
stream.Close();
}
//显示线程池现状
static void ThreadPoolMessage(string data)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("{0}\n CurrentThreadId is {1}\n " +"WorkerThreads is:{2}
CompletionPortThreads is :{3}",
data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());
Console.WriteLine(message);
}
public class FileData
{
public FileStream Stream;
public int Length;
public byte[] ByteData;
}
/// <summary>
/// 读文件的回调函数
/// </summary>
/// <param name="result"></param>
static void CallbackRead(IAsyncResult result)
{
ThreadPoolMessage("CallbackRead");
//把AsyncResult.AsyncState转换为FileData对象,以FileStream.EndRead完成异步读取
FileData fileData = (FileData)result.AsyncState;
int length = fileData.Stream.EndRead(result);
fileData.Stream.Close();
//如果读取到的长度与输入长度不一致,则抛出异常
if (length != fileData.Length)
throw new Exception("Stream is not complete!");
string data = Encoding.ASCII.GetString(fileData.ByteData, 0, fileData.Length);
Console.WriteLine(data.Substring(2, 22));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 1
</div><div><div></div></div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
</div>