創建多線程之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'))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM