1)第一代计算机(1940~1955)python
一、第二代计算机(1955~1965):晶体管和批处理系统程序员
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/18/2018 4:14 PM "" """ 开启子进程的两种方式 """ #开启进程的方式1: from multiprocessing import Process import time def task(name): """ 任务函数 :param name: :return: """ print('%s is running'%name) time.sleep(3) print('%s is done'%name) if __name__ == '__main__': #Process(target= task, kwargs={'name':'子进程1'}) p = Process(target = task, args = ('子进程1',)) p.start()#仅仅只是给操做系统发送了一个信号; print('主') """ 主 子进程1 is running 子进程1 is done """ """ 开启进程的方式2: """ from multiprocessing import Process import time class MyProcess(Process): def __init__(self,name): super().__init__() self.name = name def run(self):#默认必须叫作run print('%s in running'%self.name) time.sleep(3) print('%s is done'%self.name) if __name__ == '__main__': p = MyProcess('子进程1') p.start() print('主') """ 主 子进程1 in running 子进程1 is done """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/18/2018 4:52 PM "" """ 10-查看进程的pid与ppid 操做系统管理进行,使用pid号,相似人类的身份证号; """ from multiprocessing import Process import time import os def task(): print('%s is running,partent id is <%s>'%(os.getpid(),os.getppid())) time.sleep(3) print('%s is done,partent id is <%s>'%(os.getpid(),os.getppid())) if __name__ == '__main__': #p = Process(target= task, args=('子进程1'))#TypeError: task() takes 0 positional arguments but 4 were given p = Process(target= task,) p.start() print('主%s,partent id is <%s>'%(os.getpid(),os.getppid())) """ 主 12040 16924 is running 16924 is done ---------------------- 主888,partent id is <14600> 19400 is running,partent id is <888> 19400 is done,partent id is <888> ----------------------------------- C:\\Users\\TQTL911>tasklist |findstr pycharm pycharm64.exe 14600 Console 6 823,488 K C:\\Users\\TQTL911> """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/18/2018 5:07 PM "" """ 11-僵尸进程与孤儿进程; 此内容了解为主; 一、僵尸进程,即子进程被杀死后的状态,方便于父进程查看一些状态信息,但他是有害的; 二、孤儿进程,即父进程终止后,保存的子进程,但会交由祖宗进程init(全部进程的起点,即孤儿院)去进行管理,它是无害的; """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/18/2018 5:17 PM "" """ 12-Process对象的其余属性或方法 """ #一、join方法讲解 from multiprocessing import Process import time import os import random def task(): print('%s is running,The parent id is <%s>'%(os.getpid(),os.getppid())) time.sleep(random.randrange(1,5)) print('%s is down,The parent id is <%s>'%(os.getpid(),os.getppid())) if __name__ == '__main__': p = Process(target=task,) p.start() p.join()#保证等待子进程执行结束,父进程才执行 print('主',os.getpid(),os.getppid()) print(p.pid) #二、引入join方法 from multiprocessing import Process import time import os import random def task(name): print('%s is running'%name) time.sleep(random.randrange(1,3)) if __name__ == '__main__': p1 = Process(target=task,args=('子进程1',)) p2 = Process(target=task,args=('子进程2',)) p3 = Process(target=task,args=('子进程3',)) p4 = Process(target=task,args=('子进程4',)) p1.start()#只是发个信号给操做系统,至于CPU执行的顺序,由操做系统来分配; p2.start() p3.start() p4.start() p1.join()#保证等待子进程执行结束,父进程才执行 p2.join()#保证等待子进程执行结束,父进程才执行 p3.join()#保证等待子进程执行结束,父进程才执行 p4.join()#保证等待子进程执行结束,父进程才执行 print('主',os.getpid(),os.getppid()) """ 一、不曾使用join方法的时候,执行的顺序以下所示: 主 14188 14600 子进程1 is running 子进程3 is running 子进程2 is running 子进程4 is running 二、使用了join方法以后,执行的顺序以下所示: 子进程1 is running 子进程2 is running 子进程3 is running 子进程4 is running 主 2564 14600 """ #三、并行执行程序; from multiprocessing import Process import os import random import time def task(name,n): print('%s is runing'%name,10) time.sleep(n) if __name__ == '__main__': start = time.time() p1 = Process(target= task, args=('子进程1',5)) p2 = Process(target= task, args=('子进程2',3)) p3 = Process(target= task, args=('子进程3',2)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() print('主',(time.time() - start)) """ 子进程1 is runing 10 子进程3 is runing 10 子进程2 is runing 10 主 5.093375205993652 """ #四、变成串行方式执行程序; from multiprocessing import Process import os import time def task(name,n): print('%s is running'%name,n) time.sleep(n) if __name__ == '__main__': start = time.time() # p1 = Process(target= task,args=('子进程1',5),) # p2 = Process(target= task,args=('子进程2',1),) # p3 = Process(target= task,args=('子进程3',2),) # # p1.start() # p1.join() # p2.start() # p2.join() # p3.start() # p3.join() #对以上内容的简写 p1 = Process(target=task, args=('子进程1', 5), ) p2 = Process(target=task, args=('子进程2', 1), ) p3 = Process(target=task, args=('子进程3', 2), ) p_l = [p1,p2,p3] for p in p_l: p.start() for p in p_l: #p.join()#TabError: inconsistent use of tabs and spaces in indentation p.join() #print('主',time.time() - start)#NameError: name 'start' is not defined print('主',time.time() - start) """ 子进程1 is running 5 子进程2 is running 1 子进程3 is running 2 主 8.224236726760864 """ #小结 from multiprocessing import Process import os import time import random def task(): print('%s is runing,The parent id is <%s>'%(os.getpid(),os.getppid())) time.sleep(random.randrange(1,3)) print('%s is done,The parent id is <%s>'%(os.getpid(),os.getppid())) if __name__ == '__main__':#尽量手写,不使用main自动生成,会出现tab != 4个空格的坑呀! # p = Process(target= task,) # p.start() # p.join() # print('主',os.getpid(),os.getppid()) # print(p.pid) # print(p.is_alive())#布尔值False or True p = Process(target=task,) p.start() p.terminate() time.sleep(3)#加上时间后,is_alive将会变成False print(p.is_alive())#True print('主',os.getpid(),os.getppid())
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/18/2018 6:53 PM from multiprocessing import Process import time import random def task(n): time.sleep(random.randrange(1,3)) print('--------->%s'%n) if __name__ == '__main__': p1 = Process(target=task,args=(1,)) p2 = Process(target=task,args=(2,)) p3 = Process(target=task,args=(3,)) # Req1:最早保证输出--------->4 p1.start() p2.start() p3.start() print('最早保证输出--------->4') #Req2:保证最后输出--------->4 p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() print('保证最后输出--------->4') #Req3:保证按顺序输出--------->4 #以下写,变成串行,失去并发的意义,没有意义,为了练习join方法的使用; p1.start() p1.join() p2.start() p1.join() p3.start() p1.join() print('保证按顺序输出--------->4')
1)server端;数据库
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/18/2018 6:37 PM from socket import * from multiprocessing import Process def talk(conn): while True: try: data = conn.recv(1024) if not data:break conn.send(data.upper()) except ConnectionResetError: break conn.close() def server(ip,port): server = socket(AF_INET,SOCK_STREAM) server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) server.bind((ip,port))#注意此处为元组形式的ip_port:(ip,port) server.listen(5) while True: conn,addr = server.accept() p = Process(target=talk,args=(conn,)) p.start() server.close() if __name__ == '__main__': server('127.0.0.1',9011)
2)client端;编程
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/18/2018 6:37 PM from socket import * client = socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',9011)) while True: msg = input('>>>:').strip() if not msg:continue client.send(msg.encode('utf-8')) data = client.recv(1024) print(data.decode('utf-8'))
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 8:26 AM "" """ 守护进程-伴随着父进程而消失; """ from multiprocessing import Process import time import random def task(name): print('%s is running'%name) time.sleep(random.randrange(1,3)) # p = Process(target=time.sleep,args=(3,)) # p.start()#AssertionError: daemonic processes are not allowed to have children if __name__ == '__main__': p = Process(target=task,args=('子进程1',)) p.daemon = True p.start() p.join() print('主进程') #练习题; from multiprocessing import Process import time def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") if __name__ == '__main__': p1=Process(target=foo) p2=Process(target=bar) p1.daemon=True#必定要在p.start()前设置,设置p为守护进程,禁止p建立子进程,而且父进程代码执行结束,p即终止运行 p1.start() p2.start() print("main-------") """ main-------#只要碰到main,就不会出现123和end123; 456 end456 """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 8:44 AM "" """ 互斥锁-互相排斥,好比生活中去卫生间,关上门,其余人必须等待; 互斥锁的原理-把并发改为串行,下降了效率,可是保证了数据安全不错乱; """ from multiprocessing import Process,Lock import time import random """ 进程之间数据不共享,可是共享同一套文件系统,因此访问同一个文件, 或同一个打印终端,是没有问题的,而共享带来的是竞争, 竞争带来的结果就是错乱,以下: """ def task(name,mutex):#mutex互斥的意思; mutex.acquire()#获取锁; print('%s 1'%name) time.sleep(random.randrange(1,2)) print('%s 2'%name) time.sleep(random.randrange(1,2)) print('%s 3'%name) mutex.release()#释放锁; if __name__ == '__main__': mutex = Lock()#生成锁 for i in range(3): p = Process(target=task,args=('进程%s'%i,mutex)) p.start() """ 一、未引入互斥锁 进程0 1 进程1 1 进程2 1 进程0 2 进程1 2 进程2 2 进程0 3 进程1 3 进程2 3 二、引入互斥锁 进程0 1 进程0 2 进程0 3 进程1 1 进程1 2 进程1 3 进程2 1 进程2 2 进程2 3 """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 8:55 AM "" """ 16-模拟抢票 """ from multiprocessing import Process,Lock import time import random import json def search(name): time.sleep(random.randrange(1,2)) dic = json.load(open('db.txt','r',encoding='utf-8')) print('<%s> 查看到剩余票数[%s]'%(name,dic['count'])) def get(name): time.sleep(random.randrange(1,2))#模拟读取数据的网络延迟: dic = json.load(open('db.txt','r',encoding = 'utf-8')) if dic['count'] > 0: dic['count'] -= 1 time.sleep(2) json.dump(dic,open('db.txt','w',encoding='utf-8')) print('<%s>购票成功'%name) def task(name): search(name) get(name) if __name__ == '__main__': for i in range(10): p = Process(target = task,args=('路人%s'%i,)) p.start() """ <路人0> 查看到剩余票数[1] <路人1> 查看到剩余票数[1] <路人2> 查看到剩余票数[1] <路人4> 查看到剩余票数[1] <路人3> 查看到剩余票数[1] <路人6> 查看到剩余票数[1] <路人5> 查看到剩余票数[1] <路人7> 查看到剩余票数[1] <路人8> 查看到剩余票数[1] <路人9> 查看到剩余票数[1] <路人0>购票成功 <路人1>购票成功 <路人2>购票成功 <路人4>购票成功 <路人3>购票成功 <路人6>购票成功 <路人5>购票成功 <路人7>购票成功 <路人8>购票成功 <路人9>购票成功 """ #加锁处理:购票行为由并发变成了串行,牺牲了运行效率,但保证了数据安全 from multiprocessing import Process,Lock import time import random import json def search(name): time.sleep(random.randrange(1,2)) dic = json.load(open('db.txt','r',encoding='utf-8')) print('<%s> 查看到剩余票数[%s]'%(name,dic['count'])) def get(name): time.sleep(random.randrange(1,2))#模拟读取数据的网络延迟: dic = json.load(open('db.txt','r',encoding = 'utf-8')) if dic['count'] > 0: dic['count'] -= 1 time.sleep(2) json.dump(dic,open('db.txt','w',encoding='utf-8')) print('<%s>购票成功'%name) def task(name,mutex): #mutex.acquire()#此处,注意加锁的顺序; search(name) mutex.acquire() get(name) mutex.release() """ <路人0> 查看到剩余票数[1] <路人0>购票成功 <路人1> 查看到剩余票数[0] <路人2> 查看到剩余票数[0] <路人3> 查看到剩余票数[0] <路人4> 查看到剩余票数[0] <路人5> 查看到剩余票数[0] <路人8> 查看到剩余票数[0] <路人7> 查看到剩余票数[0] <路人6> 查看到剩余票数[0] <路人9> 查看到剩余票数[0] """ if __name__ == '__main__': mutex = Lock() for i in range(10): p = Process(target = task,args=('路人%s'%i,mutex)) p.start() """ <路人2> 查看到剩余票数[1] <路人0> 查看到剩余票数[1] <路人3> 查看到剩余票数[1] <路人7> 查看到剩余票数[1] <路人1> 查看到剩余票数[1] <路人6> 查看到剩余票数[1] <路人5> 查看到剩余票数[1] <路人8> 查看到剩余票数[1] <路人9> 查看到剩余票数[1] <路人4> 查看到剩余票数[1] <路人2>购票成功 """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 9:49 AM from multiprocessing import Process,Lock import time import random import json def search(name): time.sleep(random.randrange(1,2)) dic = json.load(open('db.txt','r',encoding='utf-8')) print('<%s> 查看到剩余票数[%s]'%(name,dic['count'])) def get(name): time.sleep(random.randrange(1,2))#模拟读取数据的网络延迟: dic = json.load(open('db.txt','r',encoding = 'utf-8')) if dic['count'] > 0: dic['count'] -= 1 time.sleep(2) json.dump(dic,open('db.txt','w',encoding='utf-8')) print('<%s>购票成功'%name) else: print('<%s>购票失败'%name) def task(name,): #mutex.acquire() search(name) #mutex.acquire() get(name) #mutex.release() if __name__ == '__main__': #mutex = Lock() for i in range(10): p = Process(target = task,args=('路人%s'%i,))#args传值为元组,带有逗号 p.start() p.join() """ <路人0> 查看到剩余票数[1] <路人0>购票成功 <路人1> 查看到剩余票数[0] <路人1>购票失败 <路人2> 查看到剩余票数[0] <路人2>购票失败 <路人3> 查看到剩余票数[0] <路人3>购票失败 <路人4> 查看到剩余票数[0] <路人4>购票失败 <路人5> 查看到剩余票数[0] <路人5>购票失败 <路人6> 查看到剩余票数[0] <路人6>购票失败 <路人7> 查看到剩余票数[0] <路人7>购票失败 <路人8> 查看到剩余票数[0] <路人8>购票失败 <路人9> 查看到剩余票数[0] <路人9>购票失败 """ #小结: """ 一、发现使用join方法后,将并发改成串行,确实能保证数据安全,但问题连查票操做也 变成只能一个一个去查了,很明显,你们查票的时候应该是并发地去查询 而无需考虑数据正确与否,此时join与互斥锁的区别就显而易见了。 二、join是将一个任务总体串行,而互斥锁的好处则是将一个任务中的某一行代码串行,好比只让 task函数的get任务串行; def task(name,): search(name)#并发执行 Lock.acquire() get(name)#串行执行 Lock.release() """
进程彼此之间互相隔离,要实现进程间通讯(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的;json
1)建立队列的类(底层就是以管道和锁定的方式实现的)缓存
Queue([maxsize]):建立共享的进程队列,Queue是多进程安全的队列,可使用Queue实现多进程之间的数据传递。
2)Queue的参数介绍;安全
maxsize是队列中容许最大项数,省略则无大小限制。 但须要明确: 一、队列内存放的是消息而非大数据 二、队列占用的是内存空间,于是maxsize即使是无大小限制也受限于内存大小
3)主要方法介绍网络
q = Queue(n) q.put方法用以插入数据到队列中。 q.get方法能够从队列读取而且删除一个元素。
4)队列的使用多线程
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 10:04 AM "" """ 掌握队列的使用-先进先出的原则 """ from multiprocessing import Queue q = Queue(3)#设置队列数为3,注意:队列中不能放置大文件,而应该是精简的消息; q.put('hello') q.put({'a':1}) q.put([1,2,3,4]) #q.put(4) print(q.get()) print(q.get()) print(q.get()) print(q.empty())#清空队列操做;返回值为True; #print(q.get())#当队列中的数据被取空以后,再次get,程序将一直停留在这里;
生产者指的是生产数据的任务,消费者指的是处理数据的任务,在并发编程中,若是生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。一样的道理,若是消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题因而引入了生产者和消费者模式。
生产者和消费者彼此之间不直接通信,而经过阻塞队列来进行通信,因此生产者生产完数据以后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就至关于一个缓冲区,平衡了生产者和消费者的处理能力。 注意:这个阻塞队列就是用来给生产者和消费者解耦的
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 10:11 AM "" """ 19-生产者消费者模型 """ import time def producter(): for i in range(3): res = '包子%s'%i print('生产者生产了%s'%res) consumer(res) def consumer(res): time.sleep(1) print('消费者吃了%s'%res) producter() """ 生产者生产了包子0 消费者吃了包子0 生产者生产了包子1 消费者吃了包子1 生产者生产了包子2 消费者吃了包子2 """ """ #生产者与消费者之间彼此可能等待对方; #引入生产者消费者模型,在生产者与消费者之间引入一个“容器”,相似于缓存的做用; #好处之一:解耦合; #好处之二平衡了消费者和生产者之间的不对等的能力: """ from multiprocessing import Process,Queue import time def producter(q): for i in range(10): res = '包子%s'%i time.sleep(0.5)#模拟生产消耗的时间 print('生产者生产了%s'%res) q.put(res) def consumer(q): while True: res = q.get() time.sleep(1) print('消费者吃了%s'%res) if __name__ == '__main__': #中间的容器 q = Queue() #生产者 p1 = Process(target=producter,args=(q,)) #消费者们 c1 = Process(target=consumer,args=(q,)) p1.start() c1.start() print('主') """ 主 生产者生产了包子0 生产者生产了包子1 生产者生产了包子2 消费者吃了包子0 生产者生产了包子3 消费者吃了包子1 生产者生产了包子4 生产者生产了包子5 消费者吃了包子2 生产者生产了包子6 生产者生产了包子7 消费者吃了包子3 生产者生产了包子8 生产者生产了包子9 消费者吃了包子4 消费者吃了包子5 消费者吃了包子6 消费者吃了包子7 消费者吃了包子8 消费者吃了包子9 引入了队列的概念,生产者与消费者之间互不影响;但以上会出现消费者持续等待的情景 """ """ 生产者生产了包子0 生产者生产了包子1 消费者吃了包子0 生产者生产了包子2 生产者生产了包子3 生产者生产了包子4 消费者吃了包子1 生产者生产了包子5 消费者吃了包子2 生产者生产了包子6 生产者生产了包子7 消费者吃了包子3 生产者生产了包子8 生产者生产了包子9 主 消费者吃了包子4 消费者吃了包子5 消费者吃了包子6 消费者吃了包子7 消费者吃了包子8 消费者吃了包子9 Process finished with exit code 0 """ #生产者有多个; from multiprocessing import Process,Queue import time def producter(q): for i in range(10): res = '包子%s'%i time.sleep(0.5)#模拟生产消耗的时间 print('生产者生产了%s'%res) q.put(res) def consumer(q): while True: res = q.get() if res is None:break time.sleep(1) print('消费者吃了%s'%res) if __name__ == '__main__': #中间的容器 q = Queue() #生产者 p1 = Process(target=producter,args=(q,)) p2 = Process(target=producter,args=(q,)) p3 = Process(target=producter,args=(q,)) p4 = Process(target=producter,args=(q,)) #消费者们 c1 = Process(target=consumer,args=(q,)) c2 = Process(target=consumer,args=(q,)) c3 = Process(target=consumer,args=(q,)) p1.start() p2.start() p3.start() p4.start() c1.start() c2.start() c3.start() p1.join() p2.join() p3.join() p4.join() q.put(None) q.put(None) q.put(None) print('主')
这就像是一个Queue对象,但队列容许项目的使用者通知生成者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。
JoinableQueue的实例p除了与Queue对象相同的方法以外还具备: q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。若是调用此方法的次数大于从队列中删除项目的数量,将引起ValueError异常 q.join():生产者调用此方法进行阻塞,直到队列中全部的项目均被处理。阻塞将持续到队列中的每一个项目均调用q.task_done()方法为止
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 11:24 AM from multiprocessing import Process,JoinableQueue,Queue import time import random def producer(q): for i in range(3): res = '包子%s'%i time.sleep(0.5) print('生产了%s'%res) q.put(res) q.join() def consumer(q): while True: res = q.get() if res is None:break time.sleep(1) print('消费者吃了%s'%res) q.task_done() if __name__ == '__main__': #容器 q = JoinableQueue() p1 = Process(target=producer,args=(q,)) p2 = Process(target=producer,args=(q,)) p3 = Process(target=producer,args=(q,)) c1 = Process(target=consumer,args=(q,)) c2 = Process(target=consumer,args=(q,)) c1.daemon = True c2.daemon = True p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() p2.join() p3.join() print('主') """ 生产了包子0 生产了包子0 生产了包子0 生产了包子1 生产了包子1 生产了包子1 消费者吃了包子0 生产了包子2 消费者吃了包子0 生产了包子2 生产了包子2 消费者吃了包子0 消费者吃了包子1 消费者吃了包子1 消费者吃了包子1 消费者吃了包子2 消费者吃了包子2 消费者吃了包子2 主 Process finished with exit code 0 """
在传统操做系统中,每一个进程有一个地址空间,并且默认就有一个控制线程 线程顾名思义,就是一条流水线工做的过程(流水线的工做须要电源,电源就至关于cpu),而一条流水线必须属于一个车间,一个车间的工做过程是一个进程,车间负责把资源整合到一块儿,是一个资源单位,而一个车间内至少有一条流水线。
多线程(即多个控制线程)的概念是,在一个进程中存在多个线程,多个线程共享该进程的地址空间,至关于一个车间内有多条流水线,都共用一个车间的资源。例如,北京地铁与上海地铁是不一样的进程,而北京地铁里的13号线是一个线程,北京地铁全部的线路共享北京地铁全部的资源,好比全部的乘客能够被全部线路拉。
1) 来点儿英文范儿吧!并发
一、Threads share the address space of the process that created it; processes have their own address space. 二、Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process. 三、Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes. 四、New threads are easily created; new processes require duplication of the parent process. 五、Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes. 五、Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes.
2)算了,仍是别装13了,直接上中文吧!
一、开启一个字处理软件进程,该进程确定须要办不止一件事情,好比监听键盘输入,处理文字,定时自动将文字保存到硬盘,这三个任务操做的都是同一块数据,于是不能用多进程。
二、只能在一个进程里并发地开启三个线程,若是是单线程,那就只能是,键盘输入时,不能处理文字和自动保存,自动保存时又不能输入和处理文字。
threading与multiprocessing模块很是类似,具体见后者的用法章节;
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 11:53 AM "" """ 22-开启线程的两种方式 """ #回顾开进程的方式; import time import random from multiprocessing import Process def piao(name): print('%s piaoing'%name) time.sleep(random.randrange(1,3)) print('%s piao ended'%name) if __name__ == '__main__': p1 = Process(target=piao,args=('cuixiaozhao',))#必须加上,号 #调用对象下的方法,开启四个进程 p1.start() print('主') #开启线程的方式1: import time import random from threading import Thread def piao(name): print('%s piaoing'%name) time.sleep(random.randrange(1,3)) print('%s piao ended'%name) if __name__ == '__main__': t1 = Thread(target=piao,args=('cuixiaozhao',))#必须加上,号 t1.start() print('主线程1') #开启线程的方式2 from threading import Thread import time class MyThread(Thread): def __init__(self,name): super().__init__() self.name = name def run(self):#默认必须叫作run print('%s in running'%self.name) time.sleep(3) print('%s is done'%self.name) if __name__ == '__main__': t = MyThread('子线程2') t.start() print('主线程2') """ 小结: 一、起线程的两种方式与起进程的两种很是很是类似,几乎如出一辙,就是把multiprocessing换成threading便可 二、明确清楚进程与线程的概念区别: 同一个进程内的多线线程共享该进程内的地址资源 建立线程的开销要远小于建立进程的开销(建立一个进程,就是建立一个车间,设计到申请空间,并且在该空间内创建至少与一条流水线(即默认开启一个线程); 可是建立线程,就是在一个车间内造出一个新的流水线,无需申请基础空间,因此建立开销小) """
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 12:05 PM "" """ 23-进程与线程的区别: 一、开进程的开销远大于开线程; 二、同一进程内的多个线程共享该进程的地址空间 """ #区别1; import time import random from threading import Thread from multiprocessing import Process def piao(name): print('%s piaoing'%name) time.sleep(random.randrange(1,3)) print('%s piao ended'%name) if __name__ == '__main__': # p1 = Process(target=piao, args=('cuixiaozhao',)) # p1.start() """ 主线程1 cuixiaozhao piaoing cuixiaozhao piao ended """ t1 = Thread(target= piao,args=('cuitianqing',)) t1.start() print('主线程1') """ cuitianqing piaoing 主线程1 cuitianqing piao ended """ #区别2; from threading import Thread from multiprocessing import Process n = 100 def task2(): global n n = 0 if __name__ == '__main__': # p1 = Process(target=task2,) # p1.start() # p1.join()#等待子进程运行完成,结果为:主线程 100 t1 = Thread(target= task2,) t1.start()#主线程 0 t1.join() print('主线程',n) #区别3,瞅一眼pid from threading import Thread from multiprocessing import Process,current_process import os def task3(): #print(current_process().pid)#7428 print('子进程PID:%s 父进程的PPID:%s'%(os.getpid(),os.getppid()))#子进程PID:7760 父进程的PPID:19624 if __name__ == '__main__': # p1 = Process(target= task3,) # p1.start() t1 = Thread(target=task1,) t1.start() #print('主线程',current_process().pid)#主线程 19664 print('主进程',os.getpid())#主进程 7760 #区别4,瞅一眼pid from threading import Thread import os def task4(): print('子线程PID:%s '%(os.getpid()))#子线程PID:12248 if __name__ == '__main__': t1 = Thread(target=task4,) t1.start() print('主线程',os.getpid())#主线程 12248 #注意:其实没有子线程PID,线程都是相同级别的,你们地位相等,为了便于理解,才在此处称之为:子线程;
Thread实例对象的方法 # isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。 threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量。 # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 5:12 PM from threading import Thread,current_thread,active_count,enumerate import time def task(): print('%s is runing'%current_thread().getName()) time.sleep(2) print('%s is done'%current_thread().getName()) if __name__ == '__main__': t = Thread(target= task,name='子线程1') t.start() #t.setName('儿子线程1') #current_thread().setName('主线程') #print(t.is_alive())#返回值为True或者False #print(t.isAlive())#返回值为True或者False #print(t.getName()) #print('主线程',current_thread().getName()) #t.join() print(active_count()) print(enumerate())#[<_MainThread(MainThread, started 10096)>, <Thread(子线程1, started 14432)>]
不管是进程仍是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁;
1)须要强调的是:运行完毕并不是终止运行;
一、对主进程来讲,运行完毕指的是主进程代码运行完毕; 二、对主线程来讲,运行完毕指的是主线程所在的进程内全部非守护线程通通运行完毕,主线程才算运行完毕;
2)详细解释;
一、主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),而后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(不然会产生僵尸进程),才会结束; 二、主线程在其余非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。由于主线程的结束意味着进程的结束,进程总体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束;
3)验证一下吧!
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 5:27 PM "" """ 25-守护线程 """ from threading import Thread import time def sayhi(name): time.sleep(1) print('%s say hello'%name) if __name__ == '__main__': t = Thread(target= sayhi,args= ('cuixiaozhao',)) #t.setDaemon(True)#必须在t.start()以前设置; t.daemon = True #做用同上; t.start() print('主线程') #print(t.isAlive()) print(t.is_alive())#做用同上; from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') def bar(): print(456) time.sleep(3) print('end456') """ 123 456 --------main-------- end123 end456 """ if __name__ == '__main__': t1 = Thread(target= foo) t2 = Thread(target=bar) t1.daemon = True t1.start() t2.start() print('main'.center(20,'-'))
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __Author__:TQTL911 # Version:python3.6.6 # Time:7/20/2018 5:47 PM "" """ 26-互斥锁-由并行改成串行,牺牲了性能,保证了数据安全; """ #mutex from threading import Thread,Lock import time n = 100 def task(): global n mutex.acquire() temp = n time.sleep(0.1) n = temp -1 mutex.release() if __name__ == '__main__': mutex = Lock()#局部加锁 t_l = [] for i in range(100): t = Thread(target= task,) t_l.append(t) t.start() for t in t_l: t.join() print('主',n) """ 小结: 一、牺牲了效率; 二、保证了数据安全; """