研究遗传算法的一大诟病就是每次运行程序的结果并不是完全一样的,有时候能找到最优解有时候找不到最优解,这就是遗传算法的概率性导致的。那么怎么评价你的方法的好坏呐,这时候就要多次独立运行程序最后取结果的平均值或者计算算法的运行成功率。那么问题就来了,遗传算法的运行时间本来就略长,尤其当测试数据集很大且数量很多的时候,做一次实验跑完所有数据的时间有时候有点让人难以接受。于是想到了使用多线程,这样就可以同时运行多组独立的实验,最后再整合所有子线程的输出数据,计算运行成功率或者取最优解的平均值即可,怀揣着这个想法,开始尝试着用多线程编程来加快实验进度。以下是这几天的学习、实验过程和结果。

本人一直用Windows下的VS 2010编程,看了很多关于多线程编程的博客和资料之后我决定不用win32的API来实现多线程(各种函数名太长看着都懒得搞),而使用pthread的windows开发包(下载地址http://sourceware.org/pthreads-win32/下载任意版本,本人下载的是最新版pthreads-w32-2-9-1-release.zip,在VS下的配置方法稍后描述)比较方便。So, 多线程编程即将搞起来~~~

第一步:在VS2010下配置pthread
下载好pthread之后解压到任意文件夹,解压之后包含三个文件夹 Pre-built.2 pthreads.2 以及QueueUserAPCEx。在配置中需要用到的只有第一个文件夹下的东西。打开Pre-built.2文件夹会开到三个文件夹分别是dll、include、lib以及一对其他文件,从这三个文件夹就可以看出接下来要怎么配置。

1.将include路径填加为VS的包含路径。 例如我的include路径是F:\C&C++\多线程编程\pthreads-w32-2-9-1-release\Pre-built.2\include。填加该路径至包含路径

打开 属性管理器->右击->属性->VC++目录->包含目录, 将要填加的目录复制粘贴进去点击确定(主意千万不要在路径前面填加“$”符号,否则出错)

2.填加库目录。同第一步,将lib文件夹的目录填加进库目录

3.填加lib文件到附加依赖项。属性管理器->右击->属性->链接器->输入->附加依赖项。将lib文件夹下的.lib文件文件名复制粘贴在该项目下,记得每一个lib文件名换行。

4.将dll文件夹下的dll文件复制粘贴到你的VS项目根目录下。就可以开始使用pthread在VS中写多线程程序了。

第二步.编程

下面是我的程序

#include"rcpsp.h"//自己编写的头文件
#include<pthread.h>//pthread头文件,多线程的东西都在里面
//===========10个线程=========================
//每个线程是一次独立的实验,每组数据十次独立运行,所以编写十个子线程,以求快速完成实验
void* process_0(void *arg);
void* process_1(void *arg);
void* process_2(void *arg);
void* process_3(void *arg);
void* process_4(void *arg);
void* process_5(void *arg);
void* process_6(void *arg);
void* process_7(void *arg);
void* process_8(void *arg);
void* process_9(void *arg);
//==========================================
typedef struct
{
//===========Input Variables============
....
//===========Output Variables===========
.... }InputData; int main(void)
{
pthread_t p0,p1,p2,p3,p4,p5,p6,p7,p8,p9;//定义pthread变量
InputData Data[10]; //子线程输入输出数据
//=================multi threads========================= pthread_create(&p0,NULL,process_0,(void*)&Data[0]);
pthread_create(&p1,NULL,process_1,(void*)&Data[1]);
pthread_create(&p2,NULL,process_2,(void*)&Data[2]);
pthread_create(&p3,NULL,process_3,(void*)&Data[3]);
pthread_create(&p4,NULL,process_4,(void*)&Data[4]);
pthread_create(&p5,NULL,process_5,(void*)&Data[5]);
pthread_create(&p6,NULL,process_6,(void*)&Data[6]);
pthread_create(&p7,NULL,process_7,(void*)&Data[7]);
pthread_create(&p8,NULL,process_8,(void*)&Data[8]);
pthread_create(&p9,NULL,process_9,(void*)&Data[9]); pthread_join(p0,NULL);
pthread_join(p1,NULL);
pthread_join(p2,NULL);
pthread_join(p3,NULL);
pthread_join(p4,NULL);
pthread_join(p5,NULL);
pthread_join(p6,NULL);
pthread_join(p7,NULL);
pthread_join(p8,NULL);
pthread_join(p9,NULL);
//==================输出数据后处理========================
....
}

以上是我主程序的大概流程,由于pthread_create()创建子线程的时候给子线程函数的传入参数只有一个,所以当你需要给子函数传递多个函数参数或者需要传出参数的时候只能定义一个结构体,将所有输入和输出数据全部包装在结构体中,然后将结构体变量的引用传入子线程函数即可。在本例中,将所有输入输出参数全部包装在结构体InputData中,由于有十个子线程,为了避免不必要的麻烦,所以定义十个变量,用来输入和输出函数参数和返回值。

关于pthread_join( , )函数,它有两个参数,具体含义可以查阅其他博文。其作用是让主线程等待子线程结束,整个main函数是主线程,如果没有pthread_join这句代码,当主线程结束的时候,所有子线程也会被终止,而不管子线程是否已经结束,而大多数情况下,主线程会很快结束,然后创建的子线程还没有执行就随着主线程的结束而结束,所以一定要加一句等待子线程结束的代码。当然还有更简便的函数pthread_exit(),也可在所有线程的最后写上phread_exit(0)来让主线程等待所有子线程的结束。

phread.h中包含很多函数,在这里就不一一介绍,具体可参阅https://sourceware.org/pthreads-win32/manual/index.html

关于创建多少个线程才能效率更好的问题,网上和书上大部分推荐创建的线程数为CPU核数N 的2倍或者2*N+2个。所以这多线程和硬件关系特别大,如果是单核处理器,那完全不建议使用多线程,不然不但不会提高运行效率,反而线程之间的切换会占去很大一部分开销。

那么,我的实验运行速度提高了多少呐?? 答案是:没有提高。

让两台机子分别跑同一个数据集,一个采用上面的多线程方法,另一个串行执行每一组实验,经过对比,很悲伤的发现,串行的实验组跑得更快,当然和遗传算法本身也有很大的关系,每次一初始化不同,变异、交叉概率不同导致的找到解的时间就会不同,但是,这样的结果也是够让我伤心的了,搞了两天的多线程编程,查阅各种博客、去图书馆查资料,改程序,调程序,结果~~效果并不理想,也许是我的实验方法有问题,亦或是我的程序有问题,反正,多线程并没有加快我的实验进度。但是以后还是会尝试用多线程或者并行编程来加快遗传算法的实验速度的。

pthread Win32多线程编程的一些知识和感想的更多相关文章

  1. ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程

    为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...

  2. Win32多线程编程(1) — 基础概念篇

      内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...

  3. Win32多线程编程(2) — 线程控制

    Win32线程控制只有是围绕线程这一内核对象的创建.挂起.恢复.终结以及通信等操作,这些操作都依赖于Win32操作系统提供的一组API和具体编译器的C运行时库函数.本篇围绕这些操作接口介绍在Windo ...

  4. Win32多线程编程(3) — 线程同步与通信

      一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用.新线程与创建它的线程在相同的进程上下文中运行.因此,新线程可以访问进程内核对象的所有句柄.进程中的所有内存以及同一个进程中其他所有线 ...

  5. win32多线程编程

    关于多线程多进程的学习,有没有好的书籍我接触的书里头关于多线程多进程部分,一是<操作系统原理>里面讲的相关概念   一个是<linux基础教程>里面讲的很简单的多线程多进程编程 ...

  6. 多线程学习:win32多线程编程基本概念(转)

    一.定义: 1.进程和线程的区别 进程:是程序的执行过程,具有动态性,即运行的程序就叫进程,不运行就叫程序 ,每个进程包含一到多个线程.线程:系统中的最小执行单元,同一进程中有多个线程,线程可以共享资 ...

  7. 《Java多线程编程核心技术》知识梳理

    <Java多线程编程核心技术> @author ergwang https://www.cnblogs.com/ergwang/ 文章末尾附pdf和png下载链接 第1章 Java多线程技 ...

  8. .NET多线程编程(转)

    在.NET多线程编程这个系列我们讲一起来探讨多线程编程的各个方面.首先我将在本篇文章的开始向大家介绍多线程的有关概念以及多线程编程的基础知识;在接下来的文章中,我将逐一讲述.NET平台上多线程编程的知 ...

  9. [转]Delphi多线程编程入门(一)

    最近Ken在比较系统地学习Delphi多线程编程方面的知识,在网络上查阅了很多资料.现在Ken将对这些资料进行整理和修改,以便收藏和分享.内容基本上是复制粘贴,拼拼凑凑,再加上一些修改而来.各个素材的 ...

随机推荐

  1. su: /bin/bash: Permission denied带来的疑惑

    >客户一个oracle突然当机了,由于业务启动,客户下意识的重启了服务器,系统是起来了,准备切换到oracle用户下启动数据库,可以怎么都无法su切换,真是火上浇油呀,描述如下: 在root用户 ...

  2. Android无法自动创建USB打印机节点/dev/usb/lp0【转】

    本文转载自:http://blog.csdn.net/u013686019/article/details/50165059 Android: 4.4.4 一.问题分析 当把USB打印机插入Andro ...

  3. HDU3829 Cat VS Dog —— 最大独立集

    题目链接:https://vjudge.net/problem/HDU-3829 Cat VS Dog Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  4. 织梦dedecms将指定图片自动生成指定尺寸的小图、缩略图、图片的方法

    对于普通企业网站来讲,织梦原来的程序只是提供了一个缩略图,但是这样对于一些相对来说图片会比较多的网站来说,图片太大当缩略图会导致网站整体的访问速度,所以我今天就来教你织梦把一张大图转换成生成一张小图或 ...

  5. Watir: 很久以前,对Watir开始学习时候做的笔记

    1). buttons Xpath 1)Button properties browser.button(:xpath,"//input[@id='b2']/").name bro ...

  6. 利用http_load测试Web引擎性能

    http_load是基于linux平台的性能测试工具,它体积非常小,仅100KB.它以并行复用的方式运行,可以测试web服务器的吞吐量与负载. 一.获得http_load httpd_load的官方站 ...

  7. [转]如何用git将项目代码上传到github

    注册账户以及创建仓库 要想使用github第一步当然是注册github账号了.之后就可以创建仓库了(免费用户只能建公共仓库),Create a New Repository,填好名称后Create,之 ...

  8. 《StackGAN: Text to Photo-realistic Image Synthesis with Stacked GAN》论文笔记

    出处:arxiv 2016 尚未出版 Motivation 根据文字描述来合成相片级真实感的图片是一项极具挑战性的任务.现有的生成手段,往往只能合成大体的目标,而丢失了生动的细节信息.StackGAN ...

  9. bzoj3090

    树形dp 有一个比较明显的dp状态是dp[i][j]表示当前i节点的子树已经满足且i剩下j元钱的最小操作次数,这样复杂度比较高状态数已经有O(n*x)的了,转移再来x,肯定不行. 我们考虑把状态和dp ...

  10. 让padding不影响容器总长度

    增加CSS属性: box-sizing:border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;