多线程__线程理解

思路渐进目录:

  • 1、单任务
  • 2、多线程的创建
  • 3、主线程主动等待子线程退出之后执行代码
  • 4、创建线程的第二种方式_验证线程的执行顺序
  • 5、多线程共享全局变量
  • 6、给线程函数代码传递参数
  • 7、多任务的聊天工具

1、单任务

from time import sleep

def sing():
    for i in range(3):
        print("正在唱歌...%d"%i)
        sleep(1)

def dance():
    for i in range(3):
        print("正在跳舞...%d"%i)
        sleep(1)

if __name__ == '__main__':
    sing() #唱歌
    dance() #跳舞

2、多线程的创建

import time
import threading


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


if __name__ == '__main__':
    for i in range(5):
        # saySorry()
        # 创建一个线程

        # 创建一个线程执行的计划 target指定线程在执行时 执行的函数
        thd = threading.Thread(target=saySorry)

        # 启动计划 -- 创建并且执行子线程
        thd.start()

    # 查看当前进程内部存活的所有的线程列表 《主线程 子线程》 ----> len(列表) 线程数量
    # [<_MainThread(MainThread, started 139901408708352)>,
    # <Thread(Thread-1, started 139901382989568)>,
    #  <Thread(Thread-2, started 139901374596864)>,
    # <Thread(Thread-4, started 139901357811456)>,
    # <Thread(Thread-5, started 139901349418752)>,
    # <Thread(Thread-3, started 139901366204160)>]

    # print(threading.enumerate())
    # while True:
    #     if len(threading.enumerate()) == 1:
    #         print("所有的子线程都退出了")
    #         break
    #     else:
    #         time.sleep(1)

    # 默认情况下 主线程会等待所有的子线程退出之后再退出

3、主线程主动等待子线程退出之后执行代码

from time import sleep
import threading

def sing():
    for i in range(3):
        print("正在唱歌...%d"%i)


def dance():
    for i in range(3):
        print("正在跳舞...%d"%i)
        sleep(1)

if __name__ == '__main__':
    sing_thd = threading.Thread(target=sing)
    sing_thd.start()

    dance_thd = threading.Thread(target=dance)
    dance_thd.start()

    # while True:
    #     if len(threading.enumerate()) == 1:
    #         print("所有的子线程都退出了")
    #         break
    #     else:
    #         sleep(1)

    # 在主线程阻塞等待 Thread对象标识的子线程退出之后 才会继续往下执行代码
    sing_thd.join()
    dance_thd.join()

    print("太棒了")
  • 4、创建线程的第二种方式_验证线程的执行顺序
import threading
import time


class myThread(threading.Thread):
    """1 集成Thread 2 实现其中run方法 3 创建该类的实例对象 4对象.start()启动创建和执行"""
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = "I'm " + self.name + ' @ ' + str(i)  # name属性中保存的是当前线程的名字
            print(msg)

if __name__ == '__main__':
    for i in range(5):
        mt = myThread()
        mt.start()  # 创建子线程 在子线程中调用run方法

    # 多个线程执行的时候  顺序是随机 无序的
    # while True:
    #     time.sleep(1)
    #     print("主线程正在执行")

5、多线程共享全局变量

import threading
import time

g_number = 0

# 创建一把全局互斥锁
g_lock = threading.Lock()

def worker1():
    global g_number
    for i in range(1000000):

        # 尝试获取并且加锁 如果没有被锁定 就可以被我锁定; 
        # 如果已经被锁定 阻塞等待 直到成功获取并且锁定 
        g_lock.acquire()
        g_number += 1

        # 释放锁资源 解锁  未锁定 ----> 未锁定状态
        g_lock.release()
        # print(g_number)

def worker2():
    global g_number
    for i in range(1000000):
        g_lock.acquire()
        g_number += 1
        g_lock.release()
        # time.sleep(1)


if __name__ == '__main__':
    thd1 = threading.Thread(target=worker1)
    thd1.start()

    thd2 = threading.Thread(target=worker2)
    thd2.start()

    thd1.join()
    thd2.join()
    print("比赛的结果是%d" % g_number)
    # 多个线程同时修改同一个数据 会引起异常

6、给线程函数代码传递参数

import threading
import time

g_number = 0


def worker1(lock):
    global g_number
    for i in range(1000000):

        # 尝试获取并且加锁 如果没有被锁定 就可以被我锁定; 
        # 如果已经被锁定 阻塞等待 直到成功获取并且锁定 
        lock.acquire()
        g_number += 1

        # 释放锁资源 解锁  未锁定 ----> 未锁定状态
        lock.release()
        # print(g_number)

def worker2(lock):
    global g_number
    for i in range(1000000):
        lock.acquire()
        g_number += 1
        lock.release()
        # time.sleep(1)


if __name__ == '__main__':
    # 创建一把全局互斥锁
    lock = threading.Lock()
    # target指定线程在执行时 的函数  
    # args指定这个函数在执行时 所需的参数构成元组 一个元素的元祖需要在元素后加上,
    thd1 = threading.Thread(target=worker1, args=(lock,))
    thd1.start()

    thd2 = threading.Thread(target=worker2, args=(lock,))
    thd2.start()

    thd1.join()
    thd2.join()
    print("比赛的结果是%d" % g_number)
    # 多个线程同时修改同一个数据 会引起异常

7、多任务的聊天工具

import socket
import threading


# 主线程 专门以 接收屏幕输入 ----> 发送 --退出
# 创建一个子线程 专门用来收数据

def send_msg(udp_socket):
    """发送一次数据"""
    data = input("请输入你想说的话:")
    IP = input('请输入你想要聊天的IP地址:')
    port = int(input("请输入对方使用的端口:"))
    udp_socket.sendto(data.encode(), (IP, port))


def recv_msg(udp_socket):
    """循环接收数据"""
    while True:
        data, remote_address = udp_socket.recvfrom(4096)
        print("接收到来自%s 的数据:%s" % (str(remote_address), data.decode()))


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

    # 绑定端口
    udp_socket.bind(('', 9999))

    # 创建一个子线程收数据
    recv_thd = threading.Thread(target=recv_msg, args=(udp_socket,))
    recv_thd.start()

    while True:
        op = input("请输入你要进行的操作: 1 发送数据 2接收数据 3退出")
        if op == '1':
            send_msg(udp_socket)
        # elif op == '2':
        #     recv_msg(udp_socket)
        elif op == '3':
            break
        else:
            print("你输入有误")

    # 关掉套接字
    udp_socket.close()

if __name__ == '__main__':
    main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值