zoukankan      html  css  js  c++  java
  • C# 多线程文件读写整理总结

    多线程读写文件一直是一个比较常用的技术,普通的锁显得效率低下,和单线程感觉基本没有啥区别,这里参考了大牛的代码,采用了线程池技术,小菜我一直不明白异步和多线程有啥区别,后来读了个大牛的博客,才明白,为加强理解,抄袭一下吧,

    多线程相关名词概念的解释

    • 并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。
      其中两种并发关系分别是同步和互斥

    • 互斥:进程间相互排斥的使用临界资源的现象,就叫互斥。
    • 同步:进程之间的关系不是相互排斥临界资源的关系,而是相互依赖的关系。进一步的说明:就是前一个进程的输出作为后一个进程的输入,当第一个进程没有输出时第二个进程必须等待。具有同步关系的一组并发进程相互发送的信息称为消息或事件。
      其中并发又有伪并发和真并发,伪并发是指单核处理器的并发,真并发是指多核处理器的并发。
  • 并行:在单处理器中多道程序设计系统中,进程被交替执行,表现出一种并发的外部特种;在多处理器系统中,进程不仅可以交替执行,而且可以重叠执行。在多处理器上的程序才可实现并行处理。从而可知,并行是针对多处理器而言的。并行是同时发生的多个并发事件,具有并发的含义,但并发不一定并行,也亦是说并发事件之间不一定要同一时刻发生。

  • 多线程:多线程是程序设计的逻辑层概念,它是进程中并发运行的一段代码。多线程可以实现线程间的切换执行。
  • 异步:异步和同步是相对的,同步就是顺序执行,执行完一个再执行下一个,需要等待、协调运行。异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。
    异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事情。实现异步可以采用多线程技术或则交给另外的进程来处理。
    如果都是独占cpu 的业务, 比如举杠铃的业务, 在单核情况下 多线和单线 没有区别。
    总结
    1. 多线程的好处:比较容易的实现了异步切换的思想,
    2. 多线程本身程还是以同步完成,但是应该说比效率是比不上异步的。
    3. 多核的好处,就是可以同时做事情, 这个和单核完全不一样的。
  • 线程池异步读写文件

    废话不说了,直接上代码,很好理解的

    
    
    • 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} CurrentThreadId is {1} " +"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>
查看全文
  • 相关阅读:
    HTTP状态码
    firefox浏览器新建页面一直处于刷新状态解决方法
    firefox浏览器需要新建窗口时以新建标签页代替
    bash基础教程
    sqoop的导入|Hive|Hbase
    sqoop导出数据|Hive|HDFS和脚本编写
    sqoop安装
    sqoop简介和原理分析
    Oozie安装
    Oozie框架介绍
  • 原文地址:https://www.cnblogs.com/owenzh/p/13280211.html
  • Copyright © 2011-2022 走看看