【python】多任务(1. 线程)

线程执行的顺序是不确定,可以通过适当的延时,保证某一线程先执行

基础语法

# 多线程的使用方式
import threading

def test1():...
# 如果创建Thread时执行的函数,运行结束,那么意味着,这个子线程结束了


def test2():...


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

    t1.start()
    t2.start()

    print(threading.enumerate())

if __name__ == '__main__':
    main()

比较复杂的过程,通过类继承Thread类完成创建线程

import threading
import time


class MyThread(threading.Thread):
    def fun(self):
        for i in range(5):
            time.sleep(1)
            print("[%s]" % i)
            
            
if __name__ == '__main__':
    t = MyThread()
    t.start()

# start() 调用 self.run() , 涉及调用其它方法,到run函数中调用

多线程全局变量的共享

在一个函数中对全局变量进行修改的时候,到底是否需要使用global进行说明要看是否对全局变量的执行指向进行了修改,
如果修改了执行,即让全局变量指向了一个新的地方,那么必须使用global
如果,仅仅是修改了指向的空间中的数据,此时不必使用global

# 无参
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  g_num=%d--------" % g_num)

if __name__ == '__main__':
    main()


# 带参
import  threading
import  time

g_num = 100

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


def test2(temp):
    print("--------in test2 g_nums=%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  g_nums=%s--------" % str(g_nums))

if __name__ == '__main__':
    main()

多线程任务的资源竞争

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()

    time.sleep(5)

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

if __name__ == '__main__':
    main()
"""
    ----in test1 g_num=1188472----
    ----in test2 g_num=1319841----
    ----in main  g_num=1319841----
"""

互斥锁,避免资源竞争

import threading
import time


g_num = 0

def test1(num):

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


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

mutex1 = threading.Lock()
def main():



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

    t1.start()
    t2.start()

    time.sleep(1)

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

if __name__ == '__main__':
    main()

多线程版UDP聊天器

import  socket
import threading

# 接收数据
def recv_msg(udp_socket):
    while True:
        recv_data,data_from = udp_socket.recvfrom(1024)
        print("来自%s: [%s] " % (data_from, recv_data.decode('gbk')))

# 接收数据
def send_msg(udp_socket):
    while True:
        send_data = input("输入要发送的数据:")
        udp_socket.sendto(send_data.encode('gbk'),("192.168.2.193", 8080))

def main():

    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    # 2. 绑定本地信息
    udp_socket.bind(("", 7890))
    # 对方的连接信息,用的固定值,没有用变量传递

    # 创建两个线程
    t_recv = threading.Thread( target=recv_msg, args=(udp_socket,))
    t_send = threading.Thread( target=send_msg, args=(udp_socket,))

    t_recv.start()
    t_send.start()

if __name__ == '__main__':
    main()
原文地址:https://www.cnblogs.com/liudianer/p/11766547.html