python编程收尾_《Python》进程收尾线程初识

from multiprocessing import Manager

把所有实现了数据共享的比较便捷的类都重新又封装了一遍,并且在原有的multiprocessing基础上增加了新的机制list、dict

机制:支持的数据类型非常有限

list、dict都不是数据安全的,需要自己加锁来保证数据安全

from multiprocessing importManager,Process,Lockdefwork(d,lock):

with lock:

d['count'] -= 1

if __name__ == '__main__':

lock=Lock()

with Manager() as m:#m = Manager()

dic = m.dict({'count':100})

p_lst=[]for i in range(10):

p= Process(target=work, args=(dic, lock))

p_lst.append(p)

p.start()for p inp_lst:

p.join()print(dic)#{'count': 90}

with ......

一大段语句

dis模块

python的上下文管理

在执行一大段语句之前,自动做某个操作 open

在执行一大段语句之后,自动做某个操作 close

面向对象的魔术方法(双下杠杠方法)

#回调函数 in Pool

importosfrom multiprocessing importPooldeffunc(i):print('第一个任务', os.getpid())return '*'*idef call_back(res): #回调函数

print('回调函数:', os.getpid())print('res--->', res)if __name__ == '__main__':

p=Pool()print('主进程', os.getpid())

p.apply_async(func, args=(1,), callback=call_back)

p.close()

p.join()

func执行完毕之后执行callback函数

func的返回值会作为callback的参数

回调函数是在主进程中实现的

应用场景:子进程有大量运算要做,回调函数等待结果做简单处理

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

importrefrom urllib.request importurlopenfrom multiprocessing importPool

url_lst=['http://www.baidu.com','http://www.sohu.com','http://www.sogou.com','http://www.4399.com','http://www.cnblogs.com',

]defget_url(url):

response=urlopen(url)

ret= re.search('www\.(.*?)\.com', url)print('%s finished' % ret.group(1))return ret.group(1),response.read()defcall(content):

url,con=content

with open(url+'.html', 'wb')as f:

f.write(con)if __name__ == '__main__':

p=Pool()for url inurl_lst:

p.apply_async(get_url,args=(url,),callback=call)

p.close()

p.join()

子进程去访问网页子进程去处理网页的结果

二、线程理论基础

进程是计算机中最小的资源分配单位,进程对于操作系统来说还具有一定的负担

创建一个进程,操作系统分配的资源大约有:代码,数据,文件等

1、为什么要有线程

线程是轻量级的概念,他没有属于自己的进程资源,一条线程只负责执行代码,没有自己独立的代码、数据以及文件

线程是计算机中能被CPU调用的最小的单位,当前大部分计算机中的CPU都是执行的线程中的代码

线程与进程之间的关系:每一个进程中都至少有一条线程在工作

线程的特点:

同一个进程中的所有线程的资源是共享的

轻量级, 没有自己的资源

进程与线程之间的区别:

占用的资源、调度的效率、资源是否共享

线程的并行问题:

线程可以并行:java、c++,c#等

在cpython中,一个进程中的多个线程是不可以并行的

原因是:Cpython解释器内部有一把全局解释器锁GIL,所以线程不能充分利用多核,同一时刻同一进程中的线程只有一个能被cpu执行

GIL锁确实是限制了你程序的效率,但目前可以帮助你提高线程之间切换的效率

如果是想写高计算型的就要多进程或者换一个解释器

2、threading 模块

#并发

importosfrom threading importThreaddeffunc(i):print('子线程:', i, os.getpid())print('主线程', os.getpid())for i in range(10):

t= Thread(target=func, args=(i,))

t.start()

#进程和线程的差距

importosimporttimefrom threading importThreadfrom multiprocessing importProcessdeffunc(i):print('子:', os.getpid())if __name__ == '__main__':

start=time.time()

t_lst=[]for i in range(100):

t= Thread(target=func, args=(i,))

t.start()

t_lst.append(t)for t int_lst:

t.join()

end= time.time()-start

start=time.time()

t_lst=[]for i in range(100):

p= Process(target=func, args=(i,))

p.start()

t_lst.append(p)for p int_lst:

p.join()

end2= time.time()-startprint(end, end2)#0.0279843807220459 13.582834720611572

#线程间的数据共享

from threading importThread

num= 100

deffunc():globalnum

num-= 1 #每个线程都-1

t_lst=[]for i in range(100):

t= Thread(target=func) #创建一百个线程

t.start()

t_lst.append(t)for t int_lst:

t.join()print(num) #0

Thread 类的其他用法

Thread实例对象的方法#isAlive(): 返回线程是否活动的。

#getName(): 返回线程名。

#setName(): 设置线程名。

threading模块提供的一些方法:#threading.currentThread(): 返回当前的线程变量。

#threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

#threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

from threading importcurrentThread,Threaddeffunc():

time.sleep(2)

t= Thread(target=func)

t.start()print(t.is_alive()) #True(判断线程是否活着)

print(t.getName()) #Tread-1

t.setName('tt')print(t.getName()) #tt(改名字)

deffunc():print('子线程:', currentThread().ident)

time.sleep(2)print('主线程:',currentThread().ident)

t= Thread(target=func)

t.start()#currentThread().ident返回线程的pid

from threading importenumeratedeffunc():print('子进程:', currentThread().ident)

time.sleep(2)print('主进程:', currentThread().ident)for i in range(10):

t= Thread(target=func)

t.start()print(len(enumerate()))#enumerate()返回一个包含正在运行的线程的list,len(list)

from threading importactiveCountdeffunc():print('子线程:', currentThread().ident)

time.sleep(2)print('主线程:', currentThread().ident)for i in range(10):

t= Thread(target=func)

t.start()print(activeCount())#activeCount()返回正在运行的线程数量,与len(threading.enumerate())有相同的结果

3、守护线程

importtimefrom threading importThreaddeffunc():whileTrue:

time.sleep(1)print(123)deffunc2():print('func2 start')

time.sleep(3)print('func2 end')

t1= Thread(target=func)

t2= Thread(target=func2)

t1.setDaemon(True)

t1.start()

t2.start()print('主线程代码结束')#func2 start#主线程代码结束#123#123#func2 end

守护线程 是在主线程代码结束之后,再等待子线程执行结束后才结束

主线程结束  就意味着主进程结束

主线程等待所有的线程结束

主线程结束了以后  守护线程会随着主进程的结束而随之结束  不是随着代码的结束而结束

#################################################################################

线程

线程和进程之间的关系

每个进程内都有一个线程

线程是不能独立存在的

线程和进程之间的区别

同一个进程中线程之间的数据是共享的

进程之间的数据是隔离的

线程是被cpu执行的最小单位

操作系统调度

进程是计算机中最小的资源分配单位

python

GIL锁 全局解释器锁 全局锁

cpython解释器中的

锁线程 :同一时刻同一个进程只会有一个线程访问CPU

锁的是线程而不是数据

当程序是高IO型的 多线程

当程序是高计算(CPU)型的 多进程

cpu*1 ~ cpu*2

threading

Thread

守护线程 :主线程结束之后才结束

socket_server IO多路复用 + 多线程

框架 并发的效果 :多线程、协程的概念 flask

爬虫 :线程池 协程

set、dict、list

生成器

面向对象的进阶 :魔术方法

管道

socket_server的源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值