多通道批处理系统
分时系统
多个用户并行操作,并没有提供最高的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()