首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python之多任务

python之多任务

作者头像
不断折腾
发布2019-09-23 10:47:12
3770
发布2019-09-23 10:47:12
举报

多任务

什么是多任务?

通俗点说就是同一时间干多件事。

多线程实例:我们在看电影的时候一般会吃爆米花,这是同时进行的,

首先没有多线程的情况

import time

def movietheaters():

for i in range(3):

print('我在看电影')

time.sleep(1)

def foodGotEaten():

for i in range(3):

print('我在吃爆米花')

time.sleep(1)

def main():

movietheaters()

foodGotEaten()

if __name__ == "__main__":

main()

执行结果:

我在看电影

我在看电影

我在看电影

我在吃爆米花

我在吃爆米花

我在吃爆米花

这显然不是我们想要的,我们想要的是同时进行。

修改成如下:

import time

import threading

def movietheaters():

for i in range(3):

print('我在看电影')

time.sleep(1)

def foodGotEaten():

for i in range(3):

print('我在吃爆米花')

time.sleep(1)

def main():

th1 = threading.Thread(target=movietheaters)

th2 = threading.Thread(target=foodGotEaten)

th1.start()

th2.start()

if __name__ == "__main__":

main()

运行结果:

我在看电影

我在吃爆米花

我在看电影

我在吃爆米花

我在看电影

我在吃爆米花

自己在写的时候可以看到是两个两个同时输出的。

查看线程数

实例:

import threading

import time

def test1():

for i in range(3):

time.sleep(1)

print("test1===%d"%i)

def test2():

for i in range(3):

time.sleep(1)

print("test2===%d"%i)

def main():

t1 = threading.Thread(target=test1)

t2 = threading.Thread(target=test2)

t1.start()

t2.start()

# 查看所有线程

print(threading.enumerate())

lenth = len(threading.enumerate())

print('线程数为:%d'%lenth)

if __name__ == "__main__":

main()

# 我们把t1.start()叫做主线程,执行的函数叫做子线程,当函数执行完表示该线程结束。创建一个线程是在start()函数执行后。

类创建线程

方法创建线程像上面那样写,类创建线程就不行了,我们需要通过继承的方式来。

实例:

import threading

import time

class testThreading(threading.Thread):

def run(self):

for i in range(3):

time.sleep(1)

print('-----%d'%i)

if __name__ == '__main__':

t = testThreading()

t.start()

注意:在start()的时候自动调用run方法。如果你的类中还有其他方法,需要在run方法中调用。

多线程修改全局变量

num = 1

def test1():

global num

num+=2

print(num)

test1()

print(num)

我们再修改一个不可变全局变量时候添加了一个global,说明他是一个全局变量。

修改成多线程:

import threading

num = 1

def test1():

global num

num +=1

def test2():

print("test2的num值为:%d"%num)

def main():

t1 = threading.Thread(target=test1)

t2 = threading.Thread(target=test2)

t1.start()

t2.start()

if __name__ == '__main__':

main()

输出:test2的num值为:2

说明修改生效了,说明在多线程中,全局变量是共享的。

线程带参数

import threading

list = [1,2,3]

def test1(list):

list.append(4)

def test2(list):

print("test2的num值为:%s"%list)

def main():

t1 = threading.Thread(target=test1,args = (list,))

t2 = threading.Thread(target=test2,args = (list,))

t1.start()

t2.start()

if __name__ == '__main__':

main()

输出结果:test2的num值为:[1, 2, 3, 4]

添加参数:在Thread函数中加一个参数args,类型必须为元组

同样我们在test2中输出的也是带有4的列表,说明参数也是共享的。

多线程共享变量存在的问题

1、资源竞争

两个方法同时引用一个全局变量,就会出现资源竞争的情况。

例如:

import threading

import time

num = 0

def test1():

global num

for i in range(1000000):

num+=1

print("test1的num是:%d"%num)

def test2():

global num

for i in range(1000000):

num+=1

print("test2的num是:%d"%num)

def main():

t1 = threading.Thread(target=test1)

t2 = threading.Thread(target=test2)

t1.start()

t2.start()

time.sleep(5)

print(num)

if __name__ == '__main__':

main()

输出:

test2的num是:1146736

test1的num是:1203787

1203787

不是应该是2000000吗?很明显出错了!出现这种情况的原因就是同时拿num值,可能上一个方法还没有赋值,所以就加少了。怎么解决?那我就让他一次做完。也就是同步,同步的意思不是说一起,而是协同步调,按照前后次序进行运行,那就要引出一个新概念,互斥锁。我在执行test1的时候把他锁住,不让他执行test2。

互斥锁

#注意:同一个锁,在同一时间只能锁一次。会发生堵塞

# 创建一个锁,莫认没有上锁

mutex = threading.Lock()

# 上锁

mutex.acquire()

# 解锁

mutex.release()

将上面的实例修改成:

import threading

import time

num = 0

mutex = threading.Lock()

def test1():

global num

mutex.acquire()

for i in range(1000000):

num+=1

mutex.release()

print("test1的num是:%d"%num)

def test2():

global num

mutex.acquire()

for i in range(1000000):

num+=1

mutex.release()

print("test2的num是:%d"%num)

def main():

t1 = threading.Thread(target=test1)

t2 = threading.Thread(target=test2)

t1.start()

t2.start()

time.sleep(5)

print(num)

if __name__ == '__main__':

main()

输出:

test1的num是:1000000

test2的num是:2000000

2000000

解决。

但是互斥锁可以存在多个,但是一多,就会出现问题。出现死锁的情况,就是都堵塞了。

解决方法就是:添加超时时间(给一个时间,到了时间就解锁),等其他方法。

利用多线程进行udp同时收和发数据实例

import socket

import threading

def main():

udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

udp_socket.bind(("",7890))

dest_ip = input("请输入对方的ip:")

dest_port = int(input("请输入对方的接收端口:"))

t1 = threading.Thread(target=Send, args = (udp_socket,))

t2 = threading.Thread(target=Receive, args = (udp_socket,dest_ip,dest_port))

t1.start()

t2.start()

def Send(udp_socket,dest_ip,dest_port):

while True:

send_data = input("请输入需要发送的消息:")

udp_socket.sendto(send_data.encode("utf-8"),(dest_ip,dest_port))

def Receive(udp_socket):

while True:

recv_data = udp_socket.recvfrom(1024)

print(recv_data[0].decode("gbk"))

if __name__ == "__main__":

main()

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python入门到放弃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档