Blogger Template by Blogcrowds.

界面响应和数据处理分线程运行

对于有界面的程序开发,在开发过程中我们常常会面临一个问题,那就是在进行耗时操作时界面不响应,当然我们可以为耗时操作加上一个进度条,这样可以看起来舒服一点,但是对于需要进行多线程处理的耗时操作如实用OMP进行并行运算的时候,这时在OMP的for循环中实用进度条会面临一系列问题,如进度条不运行等,在面临这样的问题的时候我们最简单的想法就是将精度条独立为一个线程进行处理,因为进度条不需要在意精度,只需要表示一个运行过程而已,所以可以重新开辟一个线程进行处理,对于独立一个线程进行进度条处理的方法有很多:http://blog.csdn.net/bizhu12/article/details/6788241参照以上博客,我们可以简单的做出一个进度条线程,然而在我多次实验之后发现这样的方法存在问题:


一般进度条线程开辟完成后,我们需要在下面继续执行耗时操作的代码,在实验中我用sleep函数模拟耗时操作,试试证明在sleep过程中进度条没有任何反映,这让我很奇怪,理论上子线程应该是独立的才对,后来我找到一个比较靠谱的说法,实际上按照上述博客的说法,起始在MFC中主线程就是界面操作,而建立一个子线程对界面的操作实际上只是获取了一个界面变化的消息,这个消息依旧需要主线程进行处理,而此时我将耗时操作放在主线程中,同样阻塞了主线程,因此界面没有响应,因此单独建立一个进度条线程进行处理是行不通的。
  经过思考以后,我决定对耗时操作开辟一个线程,将耗时操作放在子线程中,这样主线程的界面可以一直响应,进度条的响应并不会由于耗时操作造成阻塞,这样在后台处理的过程中可以做到进度条的响应和耗时数据处理同时进行。然后一直等到耗时操作处理完毕,进度条停止响应,在这里又面临一个问题,如何判断耗时操作处理完毕。对于这个问题由于我采用线程池开辟线程进行处理,在判断过程中直接判断线程池中活跃线程数就可以了解到耗时操作是否处理完成。
处理核心代码如下:

上述第一个函数为耗时操作线程处理函数,第二个函数为实际处理函数,实际处理函数的代码为:

从上述代码中可以看到,主线程为进度条操作函数,而开辟的线程函数为耗时数据处理操作函数,实际上我们可以将整个数据处理流程绘制一个流程图如下,由于界面是主线程,因此界面响应应该为主线程,然后各个耗时的数据处理操作为子线程进行处理,这样的处理可以是的界面快速响应同时将耗时操作放在后台,得到比较友好的用户交互。


最后处理效果为:


0 Comments:

Post a Comment



较新的博文 较早的博文 主页