python学习--多进程多线程


多通道批处理系统

分时系统

多个用户并行操作,并没有提供最高的cpu效率

实时系统

效率很高,用在特种设备

进程

进程是一个实体!每一个进程都有自己的地址空间(文本区域,数据区域,堆栈)。

多进程不会共享全局变量,因为进程是独立的,线程之间是可以共享的

进程是一个资源分配的总和,线程是拿资源去执行

多进程多任务是多个资源每个资源至少1个人做事
多线程多任务一个资源多个人做事

# -*- coding: UTF-8 -*-

import time
import multiprocessing
import os

def test1(a):
    print("test1 start",a)
    print("test1的进程id:",os.getpid())
    print("test1的父进程id:", os.getppid())
    time.sleep(1)
    pass

def test2(b):
    print("test2 start",b)
    print("test2的进程id:", os.getpid())
    print("test2的父进程id:", os.getppid())
    time.sleep(1)
    pass

def main():
    #创建进程
    t1 = multiprocessing.Process(target=test1,args=("haha",))
    t2 = multiprocessing.Process(target=test2,args=("nihao",))
    t1.start()
    t2.start()
    print("haha")
    pass

if __name__ == '__main__':
    main()

不同进程的通信

通过队列我们可以实现进程间的通信。

# -*- coding: UTF-8 -*-

import time
import multiprocessing
import os

def test1(q):
    data = [11,22,33,44]
    #向队列里写入数据
    for i in data:
        q.put(i)
    print("已经全都写到队列里了")
    pass

def test2(q):
    #建立一个数组接收data里的数据
    waiting = list()
    #从队列里获取数据
    while True:
        data = q.get()
        waiting.append(data)
        if q.empty(): #如果队列里的东西读完了
            break
    print(waiting)
    pass

def main():
    #新建一个队列
    q = multiprocessing.Queue(4)

    t1 = multiprocessing.Process(target=test1,args=(q,))
    t2 = multiprocessing.Process(target=test2,args=(q,))
    t1.start()
    t2.start()
    pass

if __name__ == '__main__':
    main()

队列的样子

# -*- coding: UTF-8 -*-

import time
import multiprocessing
import os
from multiprocessing import Queue

def main():
    q = Queue(3)
    q.put(1)
    q.put(2)
    q.put(3)
    #q.put(4) #队列满了,程序卡住,等人取走数据后再加入
    try:
        q.put_nowait(4) #队列满了不阻塞,但是报错
    except:
        print("满了")
    #print(q.full()) #判断队列是否塞满
    print(q.get())
    print(q.get())
    print(q.get())
    #print(q.empty())
    
    pass

if __name__ == '__main__':
    main()

餐厅案例(一)

# -*- coding: UTF-8 -*-

from multiprocessing import Process,Queue
import time,random,os

def customer(q):
    while True:
        res = q.get() #get不到东西,就停住,等待put里有没有新的进来
        if res is None:break #接收到None,就结束
        time.sleep(random.randint(1,3))
        print("%s 吃 %s"%(os.getpid(),res))
    pass

def cooker(q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        res = "包子 %s"%(i)
        q.put(res)
        print("%s 生产了 %s"%(os.getpid(),res))
    q.put(None) #发送一个结束信号
    pass

def main():
    q = Queue()
    p1 = Process(target=cooker,args=(q,))
    p2 = Process(target=customer,args=(q,))
    p1.start()
    p2.start()
    print("主")
    pass

if __name__ == '__main__':
    main()

餐厅案例(二)

# -*- coding: UTF-8 -*-

from multiprocessing import Process,Queue
import time,random,os

def customer(q):
    while True:
        res = q.get() #get不到东西,就停住,等待put里有没有新的进来
        if res is None:break #接收到None,就结束
        time.sleep(random.randint(1,3))
        print("%s 吃 %s"%(os.getpid(),res))
    pass

def cooker(name,q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        res = "%s %s"%(name,i)
        q.put(res)
        print("%s 生产了 %s"%(os.getpid(),res))
    pass

def main():
    print("餐厅开业")
    q = Queue()
    p1 = Process(target=cooker,args=('红烧肉',q,))
    p2 = Process(target=cooker,args=('牛排',q,))
    p3 = Process(target=cooker,args=('果汁',q,))

    c1 = Process(target=customer,args=(q,))
    c2 = Process(target=customer, args=(q,))

    p1.start()
    p2.start()
    p3.start()

    c1.start()
    c2.start()

    p1.join()
    p2.join()
    p3.join()

    q.put(None) #几个人get发几个none
    q.put(None)
    print("厨师休息")
    pass

if __name__ == '__main__':
    main()

餐厅案例(三)

# -*- coding: UTF-8 -*-

from multiprocessing import Process,JoinableQueue
import time,random,os

def customer(q):
    while True:
        res = q.get() #get不到东西,就停住,等待put里有没有新的进来
        if res is None:break #接收到None,就结束
        time.sleep(random.randint(1,3))
        print("%s 吃 %s"%(os.getpid(),res))
        q.task_done() #向q.join()发送一个信号,证明一个数据被取走了,如果调用次数大于队列中项目的数量报错
    pass

def cooker(name,q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        res = "%s %s"%(name,i)
        q.put(res)
        print("%s 生产了 %s"%(os.getpid(),res))
    q.join() #生产完毕,使用join()进行阻塞,知道队伍中所有项目都被处理
    pass

def main():
    print("餐厅开业")
    q = JoinableQueue()
    p1 = Process(target=cooker,args=('红烧肉',q,))
    p2 = Process(target=cooker,args=('牛排',q,))
    p3 = Process(target=cooker,args=('果汁',q,))

    c1 = Process(target=customer,args=(q,))
    c2 = Process(target=customer, args=(q,))
    #开启守护进程,daemon的意思是主进程结束后直接把daemon结束,不管有没有吃完
    c1.daemon = True
    c2.daemon = True

    p_1 = [p1,p2,p3,c1,c2]
    for p in p_1:
        p.start()

    p1.join()
    p2.join()
    p3.join()

    print("厨师休息了")
    pass

if __name__ == '__main__':
    main()

锁进程

# -*- coding: UTF-8 -*-

from multiprocessing import Manager,Process,Lock

def work(d,lock):
    with lock: #不加锁还共享数据,就会混乱
        d['count'] -=1
    pass

def main():
    lock = Lock()
    with Manager() as m:  #实现数据共享,但是共享就意味着一起修改数据,所以加锁一个个来
        dic = m.dict({'count':100})
        p_1 = []
        for i in range(100):
            p = Process(target=work,args=(dic,lock))
            p_1.append(p)
            p.start()
        for p in p_1:
            p.join()
        print(dic)
    pass

进程池

from multiprocessing import Pool
import time 
def fun(n):    
	for i in range(10):        
		print(n+1)    
	pass 
def main():    
	starttime = time.time() #当前时间
	pool = Pool(5)
	pool.map(fun,range(100)) #⼀一百个任务
	t2 = (time.time()-starttime)
	print(t2)
	pass
if __name__ == '__main__':
	main()

同步调用

from multiprocessing 
import Pool 
import time,os 
def work(n):    
	print("%s is run"%(os.getpid()))    
	time.sleep(3)    
	return n**2    
	pass 
def main():    
	p = Pool(3) #进程池中从⽆无到有创建3个进程,以后都他们做事    
	res_l = []    
	for i in range(5):        
		res = p.apply(work,args=(i,))#同步调⽤用,直到拿到res为⽌
		res_l.append(res)    
	print(res_l)    
	pass 
if __name__ == '__main__':    
	main() 

异步执行

from multiprocessing import Pool 
import time,os 
def work(n):    
	print("%s is run"%(os.getpid()))    
	time.sleep(3)    
	return n**2    
	pass 
def main():    
	p = Pool(3) #进程池中从⽆无到有创建3个进程,以后都他们做事    
	res_l = []    
	for i in range(5):        
		res = p.apply_async(work,args=(i,))#异步调⽤用,同时去做事,返回的是队列列的内存地址!!!!        
		res_l.append(res)    
		#如果⽤用异步,主进程需要使⽤用join,等进程池任务都完成之后,才可以⽤用get采集结果    
		#如果不不⽤用close和join,主进程结束,进程池还没来得及结束,也就跟着⼀一起结束了了    
	p.close()    
	p.join()    
	for res in res_l:        
		print(res.get())    
		pass 
if __name__ == '__main__':    
	main()

多进程多⼈人连接聊天

服务端

# -*- coding: UTF-8 -*-

import socket
from multiprocessing import Pool
import os

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#当socket被关闭之后,端⼝⽴刻被重⽤
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5)
def talk(conn):
 	print("进程pid:%s"%(os.getpid()))
 	while True:
 		try:
 			msg = conn.recv(1024).decode("utf-8")
 			if not msg:break
 			conn.send(msg.encode("utf-8"))
 		except:
 			break
 	pass
def main():
 	p = Pool(4)
 	while True:
 		conn,addr = server.accept()
 		p.apply_async(talk,args=(conn,))
 	pass
if __name__ == '__main__':
 	main()

客户端

# -*- coding: UTF-8 -*-

import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",8080))
def main():
 	while True:
 		msg = input("-->").strip()
 		if not msg:continue
 		client.send(msg.encode("utf-8"))
 		msg = client.recv(1024)
 		print(msg.decode("utf-8"))
 	pass
 	
if __name__ == '__main__':
 	main()

多线程

进程:⼀个时间⼲⼀件事,如果想同时⼲多件事,不⾏
进程在执⾏过程中如果遭到阻塞,进程就会被挂起,⽆法执⾏
线程:
同⼀个进程的线程是共享资源的
线程切换很快
全局解释器GIL锁:
限制python多线程能⼒

# -*- coding: UTF-8 -*-

from threading import Thread
import time

def sayhi(name):
 	time.sleep(2)
 	print("%s say hello"%(name))
def main():
 	t = Thread(target=sayhi,args=('xiaoming',))
 	t.start()
 	print("主线程")
 	pass
 	
if __name__ == '__main__':
 	main()

多线程端⼝扫描器改造

# -*- coding: UTF-8 -*-

#⽀持命令的端⼝扫描器
import socket,sys
from optparse import OptionParser
from threading import Thread
#判断端⼝是否开放

def open(ip,port):
 	s = socket.socket()
 	try:
 		s.connect((ip,port))
 		return True
 	except:
 		return False
 		pass
 		
#默认扫描函数
def scan(ip,port):
 	if open(ip,port):
 		print("%s host %s port open"%(ip,port))
 	else:
 		print("%s host %s port close" % (ip, port))
 	pass
 	
#范围扫描
def rscan(ip,s,e):
 	for x in range(s,e):
 		if open(ip,x):
 			print("%s host %s port open"%(ip,x))
 		else:
 			print("%s host %s port close" % (ip, x))
 	pass
 		
def main():
 	usage = "usage:xxx.py -i ip地址 -p 端⼝"
 	parse =OptionParser(usage=usage)
 	parse.add_option("-i","--ip",type="string",dest="ipaddress",help="your target ip here")
 	parse.add_option("-p","--port",type="string",dest="port",help="your target port here")
 	(option,args)=parse.parse_args()
 	ip = option.ipaddress
 	port = option.port
 	
 	defaultport = [135, 139, 445, 1433, 3306, 3389, 5944]
 	
 	if ',' in port: #xx.py ip 80,21,89
 		port = port.split(',')
 		a = []
 		for x in port:
 			a.append(int(x))
 		defaultport = a
 		#scan(ip,defaultport)
 		for i in defaultport:
 			i= int(i)
			s = Thread(target=scan,args=(ip,i,))
 			s.start()
 			
 	elif '-' in port: #xx.py ip 80-99
 		port = port.split('-')
 		s = int(port[0])
 		e = int(port[1])
 		#rscan(ip,s,e)
 		for i in range(s,e):
 			s = Thread(target=scan,args=(ip,i,))
 			s.start()
 	elif 'all' in port:
 		for i in range(65535):
 			i = int(i)
 			s = Thread(target=scan, args=(ip, i,))
 			s.start()
 	elif 'default' in port:
 		for i in defaultport:
 			i = int(i)
 			s = Thread(target=scan, args=(ip, i,))
 			s.start()
 	pass
 	
if __name__ == '__main__':
 	main()
发布了21 篇原创文章 · 获赞 3 · 访问量 979

猜你喜欢

转载自blog.csdn.net/weixin_46097280/article/details/104016853