Python控制多进程与多线程并发数

Python控制多进程与多线程并发数
python

0x01    前言数组

    原本写了脚本用于暴力破解密码,但是1秒钟尝试一个密码2220000个密码个人天,想用多线程但是只会一个for全开,难道开2220000个线程吗?只好学习控制线程数了,官方文档很差看,以为结构不够清晰,网上找不少文章也都不很清晰,只有for全开线程,没有控制线程数的具体说明,最终终于根据多篇文章和官方文档算是搞明白基础的多线程怎么实现法了,怕长时间不用又忘记,找着麻烦就贴这了,跟我同样新手也能够参照参照。多线程

    先说进程和线程的区别:
            (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有本身独立的地址空间;
            (2)资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
            (3)线程是处理器调度的基本单位,但进程不是.
            (4)两者都可并发执行.并发

    不能理解的话简单打比方就是一个进程就像一个程序同样,并发互不干扰。一个进程靠一个或多个线程执行处理,并发的线程是cpu在不停的来回切换执行,固然是快到你感受不出的。app

    拿上面我遇到的困难来讲吧,大量的数据须要执行相同的处理,一个操做中间可能会有一些等待时间,一个一个执行浪费大量时间,那么就同时执行吧,咱们能够用两种并行办法:dom

    进程并行或者线程并行函数

    各有优缺点,要看状况,不是绝对的,在此不讨论这个,这引出下面两种Python并行处理方法(注释感受很清晰详细了,再也不多说)学习

    忘记说了,看留言才想起来,这里贴出了两种方法是为了理解两种的区别和相同点,可是讨论的是python,python是又全局解释器锁(GIL),他会将进程中的线程序列化,也就多核cpu实际上并不能达到并行提升速度的目的,而使用多进程则是不受限的,因此实际应用中都是推荐多进程的,也就是第一种,简单又高效,下面多线程能够做为对比(参考文章)
ui

0x02    进程处理方法spa

#coding:utf-8
import random
from time import sleep
import sys
import multiprocessing
import os
#
#需求分析:有大批量数据须要执行,并且是重复一个函数操做(例如爆破密码),若是所有开始线程数N多,这里控制住线程数m个并行执行,其余等待
#
lock=multiprocessing.Lock()#一个锁
def a(x):#模拟须要重复执行的函数
    lock.acquire()#输出时候上锁,不然进程同时输出时候会混乱,不可读
    print '开始进程:',os.getpid(),'模拟进程时间:',x
    lock.release()
    
    sleep(x)#模拟执行操做
    
    lock.acquire()
    print '结束进程:',os.getpid(),'预测下一个进程启动会使用该进程号'
    lock.release()
list=[]
for i in range(10):#产生一个随机数数组,模拟每次调用函数须要的输入,这里模拟总共有10组须要处理
    list.append(random.randint(1,10))
    
pool=multiprocessing.Pool(processes=3)#限制并行进程数为3
pool.map(a,list)#建立进程池,调用函数a,传入参数为list,此参数必须是一个可迭代对象,由于map是在迭代建立每一个进程

输出:

0x03    线程处理方法:

#coding:utf-8
import threading
import random
import Queue
from time import sleep
import sys
#
#需求分析:有大批量数据须要执行,并且是重复一个函数操做(例如爆破密码),若是所有开始线程数N多,这里控制住线程数m个并行执行,其余等待
#
#继承一个Thread类,在run方法中进行须要重复的单个函数操做
class Test(threading.Thread):
    def __init__(self,queue,lock,num):
        #传递一个队列queue和线程锁,并行数
        threading.Thread.__init__(self)
        self.queue=queue
        self.lock=lock
        self.num=num
    def run(self):
        #while True:#不使用threading.Semaphore,直接开始全部线程,程序执行完毕线程都还不死,最后的print threading.enumerate()能够看出
        with self.num:#同时并行指定的线程数量,执行完毕一个则死掉一个线程
            #如下为须要重复的单次函数操做
            n=self.queue.get()#等待队列进入
            lock.acquire()#锁住线程,防止同时输出形成混乱
            print '开始一个线程:',self.name,'模拟的执行时间:',n
            print '队列剩余:',queue.qsize()
            print threading.enumerate()
            lock.release()
            sleep(n)#执行单次操做,这里sleep模拟执行过程
            self.queue.task_done()#发出此队列完成信号
threads=[]
queue=Queue.Queue()
lock=threading.Lock()
num=threading.Semaphore(3)#设置同时执行的线程数为3,其余等待执行
#启动全部线程
for i in range(10):#总共须要执行的次数
    t=Test(queue,lock,num)
    t.start()
    threads.append(t)
    #吧队列传入线程,是run结束等待开始执行,放下面单独一个for也行,这里少个循环吧
    n=random.randint(1,10)
    queue.put(n)#模拟执行函数的逐个不一样输入
#吧队列传入线程,是run结束等待开始执行
#for t in threads:
#    n=random.randint(1,10)
#    queue.put(n)
#等待线程执行完毕
for t in threads:
    t.join()
queue.join()#等待队列执行完毕才继续执行,不然下面语句会在线程未接受就开始执行
print '全部执行完毕'
print threading.active_count()
print threading.enumerate()

输出:

其实我也仍是有些纳闷的,我在python 2.7上用多线程开死循环简单看下cpu确实多核在交替进行啊

相关文章
相关标签/搜索