多线程程序操作共享区域(文件)的一点体会

简介:      最近比较忙,很久没有写博客了,持续长时间的编程,使得我完全沦为程序匠人。但是感觉却不是想别人那么糟糕,毕业已经快两年了,我为我的编程兴趣仍然如此强烈而感到欣慰,也对一直以来比较关心的“行业应用软件架构设计”有了更深的了解,这坚定了我的信念!...

     最近比较忙,很久没有写博客了,持续长时间的编程,使得我完全沦为程序匠人。但是感觉却不是想别人那么糟糕,毕业已经快两年了,我为我的编程兴趣仍然如此强烈而感到欣慰,也对一直以来比较关心的“行业应用软件架构设计”有了更深的了解,这坚定了我的信念!

     今天晚上,终于有了一点点闲暇的时间,就想大家分享下“多线程程序操作共享区域(文件)”的一些体会吧!

 

     多线程相信大家都陌生吧,多线程程序操作共享区域应该也不陌生吧,但是大家是否经历过多CPU的服务器下同时100个线程,操作离散的文件呢?如果每个线程只负责一个固定的文件,那么问题也就不是问题了,但是如果离散的文件,有可能同时被多线程都读写的,那么是否能保证文件读写的数据一致性、是否能保证数据在存储的时候由于非次序存储而导致数据丢失呢?另外,又怎么解决同一段时间同一个线程操作同一个文件的效率问题呢,如果有方法解决,有怎么保证不出现上述第一个问题呢?

    

     摆在面前的二个问题,其实都是编写程序时候,尤其是性能要求比较高的时候,特别需要注意的问题。如下将一一介绍我的一些体会;

 

如何解决多线程多文件操作的数据一致和丢失问题

   解决这个问题,我们要先思考一下,究竟是什么原因导致这个问题呢?答案很明显,主要因为多线程多文件存储时候的时候频繁打开和频繁关闭无次序性导致的,这有点想数据库一样,DBMS是怎么来解决这个问题呢?DBMS有两个方法,一是事务、二是双端锁,其实这两个方法是一个样的道理,在这里我们就不做介绍,有兴趣大家可以查寻些其他的资料。这里我介绍实际应用中我的方法。

   

    我的方法是,保证一个文件在操作的时候,只打开一个实例,打开之后只有一次关闭。

 

    首先来看看,我是如何来设计这样的文件处理单元,我们起名为CDataHandlerUint,大家当作其为结构体就可以了,如下代码;

    typedef struct _DATA_HANDLER_UINT{queue<bool> m_OpenStatusQ; TiXmlDocument m_doc;CString m_strXmlPath;DWORD m_dwOldTicks;}CDataHandlerUint,*PCDataHandlerUint;

    由于我们操作XML文件,因此在这个结构体中,我们保存了一个打开的XML文件实例——m_doc。另外一个重要的成员是m_OpenStatusQ这个暂时命名为XML文件打开请求队列,用于记录文件读写次数。其他成员随后会逐一介绍。

 

    如下来看看,这个结构体在线程内部有是怎么用的,我们还需要一个关键的管理这个结构体的成员,CMap<CString,LPCSTR,PCDataHandlerUint,PCDataHandlerUint> m_mapHandlerUint,m_mapHandlerUint就用来管理这个结构体的。其中m_strXmlPath就是这个MAP的KEY,用来直接搜索出CDataHandlerUint的数据处理单元的pointer。

 

    那么在线程中又怎么来应用这样的一个成员呢?看下如下这个线程的处理过程就明白了;

 

    UINT32 DataHandlerThread(LPVOID pThis){

          (1) 获取要操作的文件路径

          (2) 通过文件路径,获取保存在m_mapHandlerUint的Pointer.

          (3) 如果这个Pointer为NULL,重新NEW,调用m_OpenStatusQ.push(true),之后并添加到MAP中。

         (4)如果这个Pointer不为NULL,调用m_OpenStatusQ.push(true)。

          ............

          (5) 调用m_OpenStatusQ.pop(),之后检测m_OpenStatusQ的size ,如果size为0,保存并关闭XML文件,否则,在根据m_dwOldTicks判断是否超时,如果超时同样保存并关闭XML文件,否则结束函数

    }

 

     这样就应用了MAP加上queue顺利的解决了这个问题,大家看了之后,仔细想想吧!

 

如果线程操作文件时,如果文件存在一定顺序,那么怎么提高效率呢?

     如果一个线程序遇到一个这样的文件系列怎么办,如下文件系列;

      A.xml

      A.xml

      B.xml

      B.xml

      C.xml

      ......

     从这里可以看出,文件是有顺序的,那么如何提高效率呢?

     答案就是,尽量减少文件打开和关闭次数,重复利用已经打开的文件句柄!

 

     这里程序设计的方法其实很简单,只需获取上一次操作文件句柄,并在上次操作的时候不关闭文件,关闭文件的操作放在调用之外,这样当发现两个句柄一样的时候,即调用保存并关闭,当然这里考虑到第一个问题,因此保存并关闭的条件仍然是调用m_OpenStatusQ.pop(),之后检测m_OpenStatusQ的size ,如果size为0,保存并关闭XML文件,否则,在根据m_dwOldTicks判断是否超时,如果超时同样保存并关闭XML文件,否则结束函数。

 

    上述的两个问题,两个方法,只介于本人的体会,肯定还有更好的方法,如大家有兴趣可以联系我本人,方便更深一步的探讨。

 

目录
相关文章
|
1月前
|
缓存 负载均衡 安全
在Python中,如何使用多线程或多进程来提高程序的性能?
【2月更文挑战第17天】【2月更文挑战第50篇】在Python中,如何使用多线程或多进程来提高程序的性能?
|
2月前
|
人工智能 Java API
Python 潮流周刊#28:两种线程池、四种优化程序的方法
Python 潮流周刊#28:两种线程池、四种优化程序的方法
23 1
|
4月前
|
数据采集 人工智能 数据可视化
Scala多线程爬虫程序的数据可视化与分析实践
Scala多线程爬虫程序的数据可视化与分析实践
|
2天前
|
固态存储 Ubuntu Linux
Linux(29) 多线程快速解压缩|删除|监视大型文件
Linux(29) 多线程快速解压缩|删除|监视大型文件
11 1
|
4月前
|
IDE C# 开发工具
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)
批量下载文件时使用多线程可以有效缩短完成时间,本文将讲解如何使用C#+CodePlus扩展库快速完成多线程的文件下载。 大部分代码由IDE自动生成,需要我们自己编写的代码正好**10行**。也就是说,只需要10分钟,就可以手撸一个多线程的批量下载器。
88 0
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)
|
1月前
|
算法 安全 Unix
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
30 0
|
1月前
|
消息中间件 测试技术 Python
Python使用多线程解析超大日志文件
Python使用多线程解析超大日志文件
23 0
|
2月前
|
安全 Java 开发者
Python多线程编程实战:提高程序执行效率的策略
Python多线程编程实战:提高程序执行效率的策略
124 1
|
2月前
|
Java
如何在Java中使用多线程提高程序性能
【2月更文挑战第2天】在当今的计算机应用领域中,性能是一个不可忽视的重要因素。为了提高程序的性能,我们可以采用多种方法。其中一种方法是使用多线程。本文将介绍如何在Java中使用多线程来提高程序性能。
24 2
|
2月前
|
安全 Python
如何在Python中处理多线程之间的共享状态?
如何在Python中处理多线程之间的共享状态?