python并发编程之多进程multiprocessing模块(实践篇)笔记
作者:互联网
一 multiprocessing模块介绍
python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了multiprocessing。
multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。
二 Process类的介绍与使用
通过创建一个 Process 对象然后调用它的 start() 方法来生成进程。 Process 和 threading.Thread API 相同。
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)
#参数说明
1 group参数未使用,值始终为None
2 target表示调用对象,即子进程要执行的任务
3 args表示调用对象的位置参数元组,args=(1,2,'anne',)是一个元组形式,x结尾必须有逗号
4 kwargs表示调用对象的字典,kwargs={'name':'anne','age':18}
5 name为子进程的名称
三Process类的方法
run()
表示进程活动的方法。
你可以在子类中重载此方法。标准 run() 方法调用传递给对象构造函数的可调用对象作为目标参数(如果有),分别从 args 和 kwargs 参数中获取顺序和关键字参数。
start()
启动进程活动。
这个方法每个进程对象最多只能调用一次。它会将对象的 run() 方法安排在一个单独的进程中调用。
join([timeout])
如果可选参数 timeout 是 None (默认值),则该方法将阻塞,直到调用 join() 方法的进程终止。如果 timeout 是一个正数,它最多会阻塞 timeout 秒。请注意,如果进程终止或方法超时,则该方法返回 None 。检查进程的 exitcode 以确定它是否终止。
p1.join() #表示执行完进程P1再执行主进程
主进程等待子进程,等待的是主进程,所以等待的总时间是子进程中耗费时间最长的那个进程运行的时间
一个进程可以被 join 多次。
进程无法join自身,因为这会导致死锁。尝试在启动进程之前join进程是错误的。
daemon()方法:守护进和,
p2.daemon=True #守护进程,表示主进程结束p2就结束
进程间的通信
进程之间数据不共享, 虽然可以用文件共享数据实现进程间通信,但问题是:1)效率低(共享数据基于文件,而文件是硬盘上的数据) 2)需要自己加锁处理
mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道
创建队列的类(底层就是以管道和锁定的方式实现):
Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。
相当于创建立了一个堆栈,通过put方法存入数据,get 方法取出数据 ,empt 方法判断队列是否为空
做的阿里千牛的自动回复程序
import RobotCL,time,pythoncom
import sys
from ctypes import *
from ctypes.wintypes import MSG
from ctypes.wintypes import DWORD
from KeyboardHook import *
from multiprocessing import Process,Queue
q = Queue()
#定义钩子处理函数
#参数nCode是hook类型 ,wParam和lParam参数的值依赖于Hook代码包含了关于发送或者接收消息的信息。
#keyLogger
def hookProc(nCode, wParam, lParam):
print ('nCode=',nCode, 'wParam=',wParam, 'lParam=',lParam)
print(user32.GetKeyState(0x45))
if wParam is not WM_KEYDOWN: #如果不是按键消息就放过
user32.CallNextHookEx(keyLogger.hooked, nCode, wParam, lParam)
return False
if(CTRL_CODE == int(0xFFFFFFFF&lParam[0])):#如果按下CTRL就结束
print("Ctrl pressed, call uninstallHook()")
keyLogger.uninstallHookProc()
user32.CallNextHookEx(keyLogger.hooked, nCode, wParam, lParam)
# q.put(True)
keyLogger.endKeyLog() #结束消息循环
return True
#sys.exit(-1)
hookedKey = chr(0xFFFFFFFF&lParam[0]) #chr函数返回指定的字符代码的对应字符
print("按键",hookedKey)
#q.put(False)
#print("hookProcisempty=", q.empty())
user32.CallNextHookEx(keyLogger.hooked, nCode, wParam, lParam)
return False
#实例化一个hook类
keyLogger = KeyLogger()
hp=hookProc
#取得回调函数指针
pointer = keyLogger.getFPTR(hp)
def hook(q):
if keyLogger.installHookProc(pointer):
print("installed keyLogger")
print('keyLogger=',keyLogger)
pythoncom.PumpMessages(10000)
#keyLogger.startKeyLog()
q.put(True)
print("hookisempty=", q.empty())
def Robot(q):
while True:
print('开始')
RobotA=RobotCL.RobotCL() #定义机器人
RobotA.Activate_window() #激活窗口
if RobotA.Select_friends(): #有新信息
RobotA.Activate_window() # 激活窗口
RobotA.Input_text() #输入并发送并关闭对话
time.sleep(10)
if not q.empty():
isctrl=q.get()
print("isctrl=",isctrl)
if isctrl:break
print('重新开始')
def test(q):
while True:
print("testisempty=", q.empty())
if not q.empty():
isctrl = q.get()
print("isctrl=", isctrl)
if isctrl:
break
time.sleep(5)
print('重新开始')
if __name__ == '__main__':
p1=Process(target=hook,args=(q,)) #必须加,号
#p2=Process(target=test,args=(q,))
p2=Process(target=Robot,args=(q,))
p2.daemon=True #守护进程,主进程结束p2就结束
p1.start()
p2.start()
p1.join()
#Ap2.join()
#q.put(True)
test(q)
while True:
if not q.empty():
print("q的内容", q.get())
if q.empty():
print('q打空')
break
print('主线程')
标签:Process,lParam,python,编程,keyLogger,print,进程,True,multiprocessing 来源: https://blog.csdn.net/rickcn/article/details/112887456