首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
编程语言
> 详细
完美的多线程编程方案
时间:
2015-04-13 12:30:17
阅读:
143
评论:
0
收藏:
0
[点我收藏+]
标签:
这是去年为了找工作,写的一个技术演示:以多线程暴力破解MD5密码为例,来演示一个完美的多线程编程方案。
在十年前,我写过一个单线程的暴力破解MD5密码程序(因为当时CPU还都是单核的),这次是把原来的程序多线程化了。
这个技术演示,写了多个不同实现方式的多个版本,一共花了2天时间(2014年5月3日-2014年5月4日)。
加密密码的暴力破解原理,不是本文重点,这里就不详细介绍了。
简单举例说明一下,对于尝试字符集为 a-z 26个小写字母,尝试长度为8位的话,就是把 a, b, ... z, aa, ab, ... zy, zz, aaa, ... aaaaaaaa, aaaaaaab, ... zzzzzzzy, zzzzzzzz,这26个小写字母,8位长度以内,所有的组合都尝试一遍,所以叫做暴力破解。尝试的结果,如果原加密密码在这个范围内,就必然找到。如果原加密密码不在这个范围内,那么该范围内的所有可能全部尝试完后,没有找到。尝试的方法就是对自己生成的每一个尝试串,进行和加密密码相同加密方式的加密,然后把加密后的尝试串,和加密密码进行比较,相同就说明找到了。
这种暴力破解,需要CPU进行超大量的计算。而需要CPU进行超大量计算的场景,是多线程技术的一个非常重要的应用场景。
我们以实例,来对暴力破解计算量形成一些概念:
以26个小写字母的各种组合进行尝试的话:
试完单独1位,需要对26种尝试串(a-z),进行计算和比较。
试完单独2位,需要对26+26*26=702种尝试串,进行计算和比较。
试完单独8位,需要对26的8次方+26的7次方+...+26=2171.80147158亿种尝试串,进行计算和比较。
使用四核 @3.4GHz 的CPU,以四线程(线程数超过CPU实际核数的话,速度不会提高)跑完2171.8亿种可能的话,估计要4个多小时。而以单线程跑完2171.8亿种可能的话,估计要16个小时以上。
大家有兴趣的话,可以下载本文附带的程序,自己尝试一下。
可以看到在需要CPU进行超大量计算的场景,多线程技术的使用是多么有意义。
多线程共同访问和处理同一数据源,一个非常重要的问题是,访问时需要互斥,否则的话,可能造成遗漏处理数据,或者重复处理数据。少量的重复处理数据是可以接受的,但是遗漏处理数据是不可接受的。为什么会出现重复和遗漏,我们这里不展开讲了。所以,多线程共同访问和处理同一数据源,访问时必需要互斥。
下面我们就来看一下,我所尝试过的几种实现方案。
多线程方案1:
尝试串只有1个。多个线程轮流取,然后再进行计算和比较。
这样的话,各个线程进行尝试的连续性好。但是,当一个线程在生成尝试串的过程中,另几个线程不能访问尝试串,线程需要阻塞等待。预计会经常出现这种情况,会很影响速度。
程序实现,
如果使用mutex来进行线程互斥的话,对速度的影响极为巨大,因为mutex部分代码的执行,四线程版甚至比单线程版还要慢很多很多。("ddzzzz"的md5的破解。四线程使用mutex互斥,118984ms。单线程大约13500ms。四线程比单线程还慢了8倍多)
如果使用InterlockedIncrement64,对程序的限制大。
多线程方案2:
把任务分成大致相等的n份(n为cpu的核数),然后创建n个线程,每个线程完成1份。
没有互斥的问题。
逻辑清晰性差,将来如果用于不同应用场景,代码比较难修改。
未作程序实现。
多线程方案3:
把任务分成固定的份数,然后创建n个线程(n为cpu的核数),每个线程做1份,做完之后,再去领1份,直到将所有的份数全部做完。
线程内,需要完成领一份的代码。领一份部分需要互斥。互斥部分出现的频率很少。
未作程序实现。
多线程方案4:
创建n个线程(n为cpu的核数)。
每个线程每次从总任务中,取一部分的任务进行处理,这部分任务处理完之后,再去取。直到将所有的任务全部处理完。好处是分配的比较均匀。连续性也较好。
程序实现,
"ddzzzz"的md5的破解,3线程4641ms。效果最好。
为什么说多线程方案4,是一种比较完美的多线程编程方案:
1,在一个对执行效率有很高要求的场景下,执行效率很高。
2,代码逻辑性非常好,适用性很广。很少的改动,就可以应用在很多的应用场景中。
本文所附带程序(
http://pan.baidu.com/s/1i3ip4nb
)说明:
MD5Calc.exe 图形界面,将指定的明文密码转换为MD5加密密码。
JiurlMd5CrackGui.exe 图形界面,多线程暴力破解演示程序,以本文多线程方案4实现。可以自行设定使用的线程数,默认线程数为CPU内核数减1。
TryCharset.txt 指定尝试字符集。
CryptedPassword.txt 指定要破解的密码。
临时主页:
http://blog.sina.com.cn/ddqqppb
QQ高大上交流群:91877299
完美的多线程编程方案
标签:
原文地址:http://www.cnblogs.com/jiurl/p/4421637.html
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
Spring Cloud 从入门到精通(一)Nacos 服务中心初探
2021-07-29
基础的排序算法
2021-07-29
SpringBoot|常用配置介绍
2021-07-29
关于 .NET 与 JAVA 在 JIT 编译上的一些差异
2021-07-29
C语言常用函数-toupper()将字符转换为大写英文字母函数
2021-07-29
《手把手教你》系列技巧篇(十)-java+ selenium自动化测试-元素定位大法之By class name(详细教程)
2021-07-28
4-1 YAML配置文件 注入 JavaBean中
2021-07-28
【python】 用来将对象持久化的 pickle 模块
2021-07-28
马拉车算法
2021-07-28
用Python进行冒泡排序
2021-07-28
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!