python全栈(一)网络通信与服务器之多任务-线程

代码示例讲解

01-没有多任务的程序

import time

def sing():
    """唱歌 5秒钟"""
    for i in range(5):
        print("----正在唱:菊花茶----")
        time.sleep(1)

def dance():
    """跳舞 5秒钟"""
    for i in range(5):
        print("----正在跳舞----")
        time.sleep(1)

def main():
    sing()
    dance()

if __name__ == "__main__":
    main()

02-多任务-线程-demo

import time
import threading

def sing():
    """唱歌 5秒钟"""
    for i in range(5):
        print("----正在唱:菊花茶----")
        time.sleep(1)

def dance():
    """跳舞 5秒钟"""
    for i in range(5):
        print("----正在跳舞----")
        time.sleep(1)

def main():
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()

if __name__ == "__main__":
    main()

03-让某些线程先执行

import threading
import time

def test1():
    for i in range(5):
        print("-----test1---%d---" % i)

def test2():
    for i in range(5):
        print("-----test2---%d---" % i)

def main():
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)

    t1.start()

    time.sleep(1)
    print("---1---")

    t2.start()

    time.sleep(1)
    print("---2---")

    print(threading.enumerate())

if __name__ == "__main__":
    main()

04-循环查看当前运行的线程

import threading
import time

def test1():
    for i in range(5):
        print("-----test1---%d---" % i)
        time.sleep(1)
        
    # 如果创建Thread时执行的函数,运行结束那么意味着 这个子线程结束了....

def test2():
    for i in range(10):
        print("-----test2---%d---" % i)
        time.sleep(1)

def main():
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)

    t1.start()
    t2.start()

    while True:
        print(threading.enumerate())
        if len(threading.enumerate())<=1:
            break
        time.sleep(1)

if __name__ == "__main__":
    main()

05-验证创建线程以及运行时间

注意点:
当调用Thread的时候,不会创建线程;
当调用Thread创建出来的实例对象的start方法的时候,才会创建线程以及让这个线程开始运行

import threading
import time

def test1():
    for i in range(5):
        print("-----test1---%d---" % i)
        time.sleep(1)

def main():
    # 在调用Thread之前先打印当前线程信息
    print(threading.enumerate())
    t1 = threading.Thread(target=test1)

    # 在调用Thread之后打印
    print(threading.enumerate())

    t1.start()

    # 在调用start之后打印
    print(threading.enumerate())

if __name__ == "__main__":
    main()

06-函数里面修改全局变量

num = 100
nums = [11, 22]

def test():
    global num
    num += 100

def test2():
    nums.append(33)

print(num)
print(nums)

test()
test2()

print(num)
print(nums)

07-线程共享全局变量

说明:多线程之间共享全局变量
global使用的注意点
在一个函数中对全局变量进行修改的时候,到底是否需要使用global进行说明要看是否对全局变量的执行指向进行了修改;
如果修改了执行,即让全局变量指向了一个新的地方,那么必须进行使用global;
如果仅仅是修改了指向的空间中的数据,此时不用必须使用global。
比如:字符串,元组等是不可以修改的,一旦修改,肯定是修改了指向,所以要使用global;而list是可以修改的,所以可以不使用global。
python全栈(一)网络通信与服务器之多任务-线程_第1张图片

import threading
import time

# 定义一个全局变量
g_num = 100

def test1():
    global g_num
    g_num += 1
    print("-----in test1 g_num=%d----" % g_num)

def test2():
    print("-----in test2 g_num=%d=----" % g_num)

def main():
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)

    t1.start()
    time.sleep(1)

    t2.start()
    time.sleep(1)

    print("-----in main Thread g_num = %d---" % g_num)

if __name__ == "__main__":
    main()

08-多线程共享全局变量-2

import threading
import time

def test1(temp):
    temp.append(33)
    print("-----in test1 temp=%s----" % str(temp))

def test2(temp):
    print("-----in test2 temp=%s----" % str(temp))

g_nums = [11, 22]

def main():
    # target指定将来 这个线程去哪个函数执行代码
    # args指定将来调用 函数的时候 传递什么数据过去
    t1 = threading.Thread(target=test1, args=(g_nums,))
    t2 = threading.Thread(target=test2, args=(g_nums,))

    t1.start()
    time.sleep(1)

    t2.start()
    time.sleep(1)

    print("-----in main Thread g_nums = %s---" % str(g_nums))

if __name__ == "__main__":
    main()

09-共享全局变量的问题-资源竞争

import threading
import time

# 定义一个全局变量
g_num = 0


def test1(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("-----in test1 g_num=%d----" % g_num)

def test2(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("-----in test2 g_num=%d=----" % g_num)

def main():
    t1 = threading.Thread(target=test1, args=(1000000,))
    t2 = threading.Thread(target=test2, args=(1000000,))

    t1.start()
    t2.start()

    # 等待上面的2个线程执行完毕....
    time.sleep(5)

    print("-----in main Thread g_num = %d---" % g_num)

if __name__ == "__main__":
    main()

10-使用互斥锁解决资源竞争的问题

import threading
import time

# 定义一个全局变量
g_num = 0

def test1(num):
    global g_num
    # 上锁,如果之前没有被上锁,那么此时 上锁成功
    # 如果上锁之前 已经被上锁了,那么此时会堵塞在这里,直到 这个锁被解开位置
    mutex.acquire()
    for i in range(num):
        g_num += 1
    # 解锁
    mutex.release()
    print("-----in test1 g_num=%d----" % g_num)

def test2(num):
    global g_num
    mutex.acquire()
    for i in range(num):
        g_num += 1
    mutex.release()
    print("-----in test2 g_num=%d=----" % g_num)

# 创建一个互斥锁,默认是没有上锁的
mutex = threading.Lock()

def main():
    t1 = threading.Thread(target=test1, args=(1000000,))
    t2 = threading.Thread(target=test2, args=(1000000,))

    t1.start()
    t2.start()

    # 等待上面的2个线程执行完毕....
    time.sleep(2)

    print("-----in main Thread g_num = %d---" % g_num)

if __name__ == "__main__":
    main()

11-使用互斥锁解决资源竞争的问题2

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("-----in 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("-----in test2 g_num=%d=----" % g_num)

# 创建一个互斥锁,默认是没有上锁的
mutex = threading.Lock()

def main():
    t1 = threading.Thread(target=test1, args=(1000000,))
    t2 = threading.Thread(target=test2, args=(1000000,))

    t1.start()
    t2.start()

    # 等待上面的2个线程执行完毕....
    time.sleep(2)

    print("-----in main Thread g_num = %d---" % g_num)

if __name__ == "__main__":
    main()

类来调用线程
python全栈(一)网络通信与服务器之多任务-线程_第2张图片

12-案例:多任务udp聊天器

import socket
import threading

def recv_msg(udp_socket):
    """接收数据并显示"""

    # 接收数据
    while True:
        recv_data = udp_socket.recvfrom(1024)
        print(recv_data)

def send_msg(udp_socket, dest_ip, dest_port):
    """发送数据"""
    # 发送数据
    while True:
        send_data = input("输入要发送的数据:")
        udp_socket.sendto(send_data.encode("utf-8"), (dest_ip, dest_port))

def main():
    """完成udp聊天器的整体控制"""

    # 1. 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 2. 绑定本地信息
    udp_socket.bind(("", 7890))

    # 3. 获取对方的ip
    dest_ip = input("请输入对方的ip:")
    dest_port = int(input("请输入对方的port:"))

    # 4. 创建2个线程,去执行相应的功能
    t_recv = threading.Thread(target=recv_msg, args=(udp_socket,))
    t_send = threading.Thread(target=send_msg, args=(udp_socket, dest_ip, dest_port))

    t_recv.start()
    t_send.start()

if __name__ == "__main__":
    main()

你可能感兴趣的:(网络通信与服务器,Python)