多线程

  1. 多任务的概念
    就是操作系统可以同时运行多个任务。打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务

    • 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一起执行而已)
    • 并行:指的是任务数小于等于cpu核数,即任务真的是一起执行的
      一般而言,并发的场景更多一点
  2. 线程
    在python中,我们调用thread模块进行多线程任务,python的threading模块是对thread做了一些包装的,可以更加方便的被使用
    使用多线程的例子

import threading
import time

def saySorry():
    print("亲爱的,我错了,我能吃饭了吗?")
    time.sleep(1)

if __name__ == "__main__":
    for i in range(5):
        t = threading.Thread(target=saySorry)	# 这里声明线程
        t.start() #启动线程,即让线程开始执行

我们使用threading.enumerate()来查看线程数量,它会返回一个列表

令一种使用线程的方式(类)

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = "I'm "+self.name+' @ '+str(i) #name属性中保存的是当前线程的名字
            print(msg)


if __name__ == '__main__':
    t = MyThread()
    t.start()

这里在这个类中必须要有run方法,在我们启动线程后,python会自动调用run方法启动线程。这是写进thread里面去的,没有run方法则不会被执行

  1. 优缺点
    在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据
    缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)(出现资源竞争问题)
    这里我们采用互斥锁来保证安全
import threading
import time

g_num = 0

def test1(num):
    global g_num
    for i in range(num):
        mutex.acquire()  # 上锁
        g_num += 1
        mutex.release()  # 解锁

    print("---test1---g_num=%d"%g_num)

def test2(num):
    global g_num
    for i in range(num):
        mutex.acquire()  # 上锁
        g_num += 1
        mutex.release()  # 解锁

    print("---test2---g_num=%d"%g_num)

# 创建一个互斥锁
# 默认是未上锁的状态
mutex = threading.Lock()

# 创建2个线程,让他们各自对g_num加1000000次
p1 = threading.Thread(target=test1, args=(1000000,))
p1.start()

p2 = threading.Thread(target=test2, args=(1000000,))
p2.start()

# 等待计算完成
while len(threading.enumerate()) != 1:
    time.sleep(1)

print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)

互斥锁保证代码可以完整执行完,但是,加互斥锁我们也要注意出现死锁的现象

  1. 多线程UDP版聊天器案例
import socket
import threading


def send_msg(udp_socket,recv_ip,recv_port):
	"""发送消息"""
	# 输入要发送的消息
	while True:
		send_data = input("请输入需要发送的数据:")
		udp_socket.sendto(send_data.encode("utf-8"),(recv_ip,recv_port))


def recv_msg(udp_socket):
	"""接收消息"""
	while True:
		data = udp_socket.recvfrom(1024)
		print(data)

def main():
	# 创建套接字
	udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

	# 绑定
	udp_addr = ("",9632)
	udp_socket.bind(udp_addr)

	# 接收方的地址
	recv_ip = input("请输入接收方的地址:")
	recv_port = int(input("请输入接收方的端口:"))

	t_send = threading.Thread(target=send_msg, args=(udp_socket,recv_ip,recv_port))
	t_recv = threading.Thread(target=recv_msg, args=(udp_socket,))

if __name__ == "__main__":
	main()

使用了多线程就能够让收发消息同时进行,不用像以前没有多线程版本的一样需要等待。多线程极大的提高了程序的效率

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值