python多线程结束_python 多线程

什么是线程:

在一个进程中,默认就有一个线程。将进程比喻成工厂车间的话,线程就相当于车间里的一条流水线。进程负责将资源整合到一起,而线程才是cpu上面的执行单位。

多线程:

一个进程中存在多个线程,多个线程共享该进程中的地址空间,相当于车间内的多条流水线,共享车间内的所有资源。

进程和线程的区别:

线程共享创建它的进程的地址空间。而进程有自己单独的地址空间。

线程共享其进程资源,而进程完全copy其父进程资源。

进程中的线程与线程可以直接通信,进程必须依赖进程间通信与同级进程通信。

创建线程的开销远远小于进程,不用重复开辟内存空间。

开启线程的两种方式:

#方式一

from threading importThreaddeftalk():print("%s is running"%os.getpid())if __name__ == '__main__':

t= Thread(target=talk)

t.start()print('主')#方式二

from threading importThreadimportosclassMyThread(Thread):def __init__(self,name):

super().__init__()

self.name=namedefrun(self):print("pid %s name [%s] is running"%(os.getpid(),self.name))if __name__ == '__main__':

t= MyThread("egon")

t.start()print("主",os.getpid())

创建线程的两种方式

同一进程下开启多线程和多进程的区别:

from multiprocessing importProcessfrom threading importThreaddeftalk():

start=time.time()print("%s is running"%os.getpid())print(time.time()-start)if __name__ == '__main__':#多进程,每个进程都有不同的ip

t1 = Process(target=talk)

t2= Process(target=talk)

t3= Process(target=talk)

t1.start()

t2.start()

t3.start()#多线程,每个线程的ip都和主线程一样

t4 = Thread(target=talk)

t5= Thread(target=talk)

t6= Thread(target=talk)

t4.start()

t5.start()

t6.start()print('主',os.getpid())

View Code

练习:

#服务端

importthreadingfrom socket import *phone=socket(AF_INET,SOCK_STREAM)

phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)

phone.bind(("192.168.19.115",8888))

phone.listen(5)deftalk(conn,addr):whileTrue:try:

data= conn.recv(1024)if not data:breakconn.send(data.upper())exceptException:breakconn.close()if __name__ == '__main__':whileTrue:

conn,addr=phone.accept()

p= threading.Thread(target=talk,args=(conn,addr))

p.start()#客户端

from socket import *c=socket(AF_INET,SOCK_STREAM)

c.connect(('192.168.19.115',8888))whileTrue:

msg= input(">>>:".strip())if not msg:continuec.send(msg.encode("utf-8"))

data= c.recv(1024)print(data.decode('utf-8'))

c.close()

多线程实现并发

from threading importThread

input_lis=[]

format_lis=[]deftalk():whileTrue:

msg= input(">>>:").strip()if not msg:continueinput_lis.append(msg)defformat():whileTrue:ifinput_lis:

res=input_lis.pop()

format_lis.append(res.upper())defsave():

with open("db.txt",'a')as f:whileTrue:ifformat_lis:

f.write("%s\n"%(format_lis.pop()))

f.flush()if __name__ == '__main__':

t1= Thread(target=talk)

t2= Thread(target=format)

t3= Thread(target=save)

t1.start()

t2.start()

t3.start()

模拟文件存储的过程

线程的其它属性和方法:

from threading importThread,currentThread,activeCountimportos,time,threadingdeftalk():print("%s is running"%(currentThread().getName()))if __name__ == '__main__':

t= Thread(target=talk)

t= Thread(target=talk,name = "egon")

t.start()print(t.name)#线程名

print(t.getName())print(t.is_alive())print(currentThread().getName())#默认线程名

print(threading.enumerate())#返回一个列表,同activeCount

time.sleep(3)print(t.is_alive())#是否存活

print("主",activeCount())#个数

其它属性和方法

守护线程:

无论是守护进程还是守护线程,都要遵循:守护进程(线程)会随着主进程(线程)运行结束而销毁。

对进程来说:运行结束就是主进程代码运行结束

对线程来说:运行结束必须等到所有的非守护线程运行结束后,主线程才算运行结束,因为主线程的结束以为这该进程的结束,进程的整体资源都将被回收。

from threading importThread,currentThreadimporttimedeftalk1():

time.sleep(10)#这里如果是小于或等于非守护进程的睡眠时间,将会执行下面代码print("%s is running"%currentThread().getName())#10秒时间足以让主线程和非守护线程执行结束,这句不会打印,随着主线程结束而结束

deftalk2():

time.sleep(2)print("%s is running"%currentThread().getName())if __name__ == '__main__':

t1= Thread(target=talk1)

t2= Thread(target=talk2)

t1.daemon=True

t1.start()

t2.start()print('主程序执行完成')#守护线程随着主线程的结束而结束,注意主线程是当所有的非守护线程结束后才会结束

全局解释锁GIL:

GIL的本质还是一把互斥锁,所有的互斥锁的本质都是一样,那就是将并发转成串行,以此来控制同一时间内共享数据只能被一个任务修改,从而保护数据的安全性。

保护不同的数据安全,就应该加不同的锁

GIL是把同一进程内,多个线程争抢一把锁,保证同一时刻只有一个线程在运行

在线程执行过程中与I/O,运行时间过长的时候会强制释放GUL供其他线程使用。知道该线程再次抢到GUL,基于上次继续运行。

from threading importThread,Lockimporttime

n= 100

defwork():globaln

tem=n

time.sleep(0.5)

n= tem-1

if __name__ == '__main__':

mutex=Lock()

t_lis=[]

s=time.time()for i in range(100):

t= Thread(target=work)

t_lis.append(t)

t.start()for t int_lis:

t.join()print("%s:%s"%(time.time()-s,n))#0.5403599739074707:99执行了100次但是结果是99,出现数据错乱

from threading importThread,Lockimporttime

n= 100

defwork():

mutex.acquire()globaln

tem=n

time.sleep(0.5)

n= tem-1mutex.release()if __name__ == '__main__':

mutex=Lock()

t_lis=[]

s=time.time()for i in range(100):

t= Thread(target=work)

t_lis.append(t)

t.start()for t int_lis:

t.join()print("%s:%s"%(time.time()-s,n))#50.05104112625122:0加上应用层互斥锁,运行时间长,数据安全

View Code

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值