天天看点

Python并发编程之多线程(多线程实现socket,threading常用方法示例)

四.使用多线程并发 socket 通信(tcp)

示例比较简单, 更多功能自行添加

1.服务端

from threading import Thread
from socket import *

s = socket(AF_INET,SOCK_STREAM)
s.bind(("127.0.0.1",8090))
s.listen(5)

def connection(conn):
    while 1:
        try:
            date = conn.recv(1024)
            print(date.decode("utf-8"))
            conn.send("阿巴阿巴".encode("utf-8"))
        except Exception:
            break

if __name__ == '__main__':
    while 1:
        conn,addr = s.accept()
        p = Thread(target=connection,args=(conn,))
        p.start()
           

2.客户端 (可以多台客户端)

from socket import *

c = socket(AF_INET,SOCK_STREAM)
c.connect(("127.0.0.1",8090))

while True:
    inp = input(">>").strip()
    if len(inp) == 0:continue
    c.send(inp.encode("utf-8"))
    date = c.recv(1024)
    print(date.decode("utf-8"))
           

五.使用多线程实现类似编辑器的功能

需求 : 1.接收用户输入, 2.将用户输入进行upper操作, 3.将大写的数据保存到文件

from threading import Thread

inp_li = []
upp_li = []

def inp():  # 接收用户输入
    while 1:
        date = input("用户输入>>").strip()
        if len(date) == 0:continue
        inp_li.append(date)

def upp():  # 将输入变成大写
    while 1:
        if inp_li:
            date = inp_li.pop()
            upp_li.append(date.upper())

def file():  # 将大写内容存入文件
    while 1:
        if upp_li:
            with open("a.txt","a",encoding="utf-8")as f:
                f.write(f"{upp_li.pop()}\n")

if __name__ == '__main__':
    i = Thread(target=inp)
    u = Thread(target=upp)
    f = Thread(target=file)
    i.start()
    u.start()
    f.start()
           

六.线程对象的 join 方法

同进程 join 方法一样, 让主线程等待子线程运行完毕后再运行

from threading import Thread,current_thread
import time

def task():
    time.sleep(2)
    print(f"子线程{current_thread().name}运行完毕")

if __name__ == '__main__':
    p = Thread(target=task)
    p.start()
    p.join()
    print("主线程--->")
    
'''输出
子线程Thread-1运行完毕
主线程--->
'''
           

七.线程相关的其他方法

1.Thread 对象的方法

方法 作用
p.is_alive( ) 返回线程是否存活
p.getName( ) 返回线程名
p.setName( ) 修改线程名

2.threading 模块的方法

方法 作用
threading.currentThread( ) 返回当前的线程变量
threading.enumerate( ) 返回一个包含正在运行线程的列表, 也就是存活的线程
threading.activeCount( ) 返回正在运行的线程数量, 等价于:len(threading.enumerate( ))

3.以上方法演示

from threading import Thread,current_thread
import threading
import time
def task():
    print(f"子线程打印:{current_thread().getName()}")
    time.sleep(10)

if __name__ == '__main__':
    p = Thread(target=task)
    p.start()
    time.sleep(0.1)
    print(p.is_alive()) # True
    print(p.getName())  # Thread-1
    p.setName("派大星")
    print(p.getName())  # 派大星

    p2 = Thread(target=task)
    p3 = Thread(target=task)
    p2.start()
    p3.start()
    print(threading.current_thread().name)  # 获取主线程名字
    print(threading.enumerate())     # 包含主线程在内的所有正在运行的进程
    print(threading.active_count())  # 线程对象列表

'''输出
子线程打印:Thread-1
True
Thread-1
派大星
子线程打印:Thread-2
子线程打印:Thread-3
MainThread
[<_MainThread(MainThread, started 3800)>, <Thread(派大星, started 2704)>, <Thread(Thread-2, started 18388)>, <Thread(Thread-3, started 8448)>]
4
'''
           

4.验证主线程等待子线程运行完毕

from threading import Thread,current_thread
import time

def task():
    time.sleep(2)
    print(f"子线程{current_thread().name}运行完毕")

if __name__ == '__main__':
    p = Thread(target=task)
    p.start()
    print("主线程--->")
    print(p.is_alive())

'''输出
主线程--->
True
子线程Thread-1运行完毕
'''