创建多线程之threading.Thread的使用

1.threading模块

threading模块是众多多线程管理模块的其一,它能确保重要的子线程退出后进程才退出。

multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍

(官方链接)


2.创建线程的两种方式

方式一:

from threading import Thread
import time
# 进程等待所有线程结束后才会结束

def func():
    print('线程 start')
    time.sleep(2)
    print('线程 end')

if __name__ == '__main__':

    t = Thread(target=func)
    t.start() # 告诉操作系统开一个线程
    print('主')

方式二:

from threading import Thread
import time
class Myt(Thread):
    def run(self):
        print('子线程 start')
        time.sleep(2)
        print('子线程 end')

t = Myt()
t.start()
print('主线程'


3.子进程和子线程pid的比较

from threading import Thread
from multiprocessing import Process
import os

def func():
    print('hello',os.getpid())

if __name__ == '__main__':
    # 在主进程开启多个线程,每个线程都跟主进程pid一样
    t1 = Thread(target=func)
    t2 = Thread(target=func)
    t1.start()
    t2.start()
    print('主线程/主进程pid:',os.getpid())

    # 开个多个子进程,每个进程都有不同的pid:
    p1 = Process(target=func)
    p2 = Process(target=func)
    p1.start()
    p2.start()
    print('主线程/主进程pid:', os.getpid())

4.子线程内存数据共享问题

from threading import Thread
from multiprocessing import Process

def func():
    global n
    n = 0

if __name__ == '__main__':
    # 子进程:
    n = 100
    p = Process(target=func)
    p.start()
    p.join()
    print('主',n)  # 毫无疑问子进程p已经将自己的n改成了全局的n,改成了0,但改的仅仅是它自己的,查看父进程的n仍然为100

    # 子线程:
    n = 1
    t=Thread(target=func)
    t.start()
    t.join()
    print('主',n) # 查看结果为,因为同一进程内的线程之间共享进程内的数据


5.线程的join方法

from threading import Thread
import time


def func(name,n):
    print(f'{name} start')
    time.sleep(n)
    print(f'{name} end')


t1 =Thread(target=func,args=('线程1',1))
t2 =Thread(target=func,args=('线程2',2))
t3 =Thread(target=func,args=('线程3',3 ))
start = time.time()
t1.start()
t2.start()
t3.start()

t1.join()   # 等待子线程运行结束
t2.join()
t3.join()
end = time.time() #
print(end-start)   # 3.0060362

6.Thread类的其他方法

  • isAlive():返回线程是否活动的。
  • getName():返回线程名。
  • setName():设置线程名。

threading模块提供的一些方法:

  • threading.currentThread():返回当前的线程变量。
  • threading.enumerate():返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  • threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate()) 有相同的结果。
from threading import Thread,currentThread,enumerate,activeCount
import time

def task():
    print('子线程 start')
    time.sleep(2)
    print('子线程 end')
    print(enumerate())
    # print(currentThread(),'子线程')
if __name__ == '__main__':
   t1 = Thread(target=task)
   t2 = Thread(target=task)
   t1.start()
   t2.start()



   # print(t1.is_alive()) # True
   # print(t1.getName()) # Thread-1
   # print(t2.getName()) # Thread-2
   # t1.setName('班长')
   # print(t1.getName())
   print(currentThread().name)
   # print(enumerate()) # [<_MainThread(MainThread, started 1856)>, <Thread(Thread-1, started 6948)>, <Thread(Thread-2, started 3128)>]
   print(activeCount()) # 3
   # print(len(enumerate())) # 3

7.多线程实现socket

server服务端

import socket
from threading import Thread

s=socket.socket()
s.bind(('127.0.0.1',8080))
s.listen(5)

def run(conn):
    while True:
        try:
            data = conn.recv(1024)
            print(data)
            conn.send(data.upper())
        except Exception:
            break

if __name__ == '__main__':
    while True:
        print('等待客户端连接')
        conn,addr = s.accept()
        print(f'客服端{addr}连接成功')
        t = Thread(target=run,args=(conn,))
        t.start()

client客户端

import socket
s = socket.socket()
s.connect(('127.0.0.1',8080))
while True:
    msg = input('>>>:').strip()
    if not msg:
        continue
    s.send(msg.encode('utf-8'))
    data = s.recv(1024)
    print(data.decode('utf-8'))
posted @ 2019-09-17 22:12  tomjoy  阅读(21394)  评论(0编辑  收藏  举报