在Python中使用多线程创建一个新的线程成本是比较高的,因为涉及大量与操作系统之间的交互。
所以当程序中需要大量使用生存周期很短的线程时,线程池比较适合。另外线程池可以有效的控制系统中并发线程的数量,当系统中含有大量的并发线程的时候可能会导致系统性能急剧下降,甚至导致Python解释器崩溃。
通常当我们使用Python编写exp的时候首先选择线程池来完成多线程任务。
0x01 线程池创建
Python中线程池的创建主要使用Threadpool模块。
pool = threadpool.ThreadPool(pools)reqs = threadpool.makeRequests(some_callable, list_of_args, callback)[pool.putRequest(req) for req in reqs]pool.wait()
1、代码第一行定义了一个线程池,表示最多可以创建poolsize这么多线程。
2、第二行调用makeRequests创建了要开启多线程的函数。
参数表示:函数相关参数和回调函数,其中回调函数可以不写,default是无,也就是说makeRequests只需要2个参数就可以运行;
3、第三行的用法其实比较奇怪,是将所有要运行多线程的请求扔进线程池。等同于
for req in requests:pool.putRequest(req)
4、第四行是等待所有的线程完成工作后退出。
0x02 函数封装
通常在编写exp的过程中我们会将线程池创建的代码封装成一个函数,来提高代码的简洁性与可读性。
def multithreading(funcname, filename="url.txt", pools=5):works = []with open(filename, "r") as f:for i in f:func_params = [i.rstrip("\n")]works.append((func_params, None))pool = threadpool.ThreadPool(pools)reqs = threadpool.makeRequests(funcname, works)[pool.putRequest(req) for req in reqs]pool.wait()
如以上代码示例我们将线程池的创建代码封装成为一个函数,实现任何一个可执行函数均可直接使用该函数来利用线程池进而高效地完成任务,其中将funcname作为函数名传入即可,work则为函数执行过程中具体的参数。
0x03 代码实例
如下定义一个函数实现批量检测网站存活动函数
def check(url):req = request.get(url)if req.status_code == 200:print("发现存活站点URL:",url)
多线程执行即可。
multithreading(check,url.txt,8)
文章转载自自述小屋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




