线程

线程

一、初识线程

1.1 什么是线程

操作系统 —— 工厂
进程 —— 车间
线程—— 流水线
cpu —— 电源
线程:cpu最小的执行单位
进程:资源集合/资源单位
线程运行 = 运行代码
进程运行 = 各种资源 + 线程

1.2 线程和进程的区别

线程 进程
同一个进程下的线程资源共享 内存空间彼此隔离
快:只是告诉操作系统一个执行方案 慢:需要申请资源开辟空间

二、开启线程的两种方式

'''方式一'''
from threading import  Thread
import time

def task():
    print('子线程开始')
    time.sleep(1)
    print('子线程结束')

if __name__ == '__main__':
    t = Thread(target=task)   #初始化一个对象
    t.start()
    time.sleep(2)
    print('主线程结束')
'''方式二'''
from threading import  Thread
import time

class task(Thread):
    print('子线程开始')
    time.sleep(1)
    print('子线程结束')

t = task()
t.start()
time.sleep(2)
print('主线程结束')

三、线程与进程的速度对比

from multiprocessing import Process
from threading import Thread
import time

def task(name):
    print(f"{name}在运行")
    time.sleep(3)
    print(f"{name}结束")

if __name__ == '__main__':
    p = Process(target=task,args=('子进程',))
    t = Thread(target=task,args=('子线程',))
    p.start()
    t.start()
    time.sleep(5)
    print('主')
    
'''
子线程在运行
子进程在运行
子线程结束
子进程结束
主
### 充分证明了线程比进程快
'''

四、证明子线程共享资源

from threading import Thread


x = 100
def task():
    global x
    x = 1

if __name__ == '__main__':
    t = Thread(target=task)
    t.start()
print(x)  #如果x被改为1,则证明子线程共享资源  #1
'''
综上所述,充分证明子线程共享资源
'''

五、线程的相关方法

5.1 join方法

等待子线程运行结束

'''join 方法'''

from threading import Thread
import time

def task(name,n):
    print(f'{name}开始')
    time.sleep(n)
    print(f'{name}结束')

if __name__ == '__main__':
    t1 = Thread(target=task,args=('子线程1',1))
    t2 = Thread(target=task,args=('子线程2',2))
    t3 = Thread(target=task,args=('子线程3',3))

    l = [t1,t2,t3]
    for t in l:
        t.start()
    t.join()  #感知子线程的结束 
    print('主线程结束')
    print(t.is_alive())  #查看t线程是否还活着,false 证明死了

5.2 其他方法

'''

Thread实例对象的方法
  # isAlive(): 返回线程是否活动的。
  # getName(): 返回线程名。
  # setName(): 设置线程名。

threading模块提供的一些方法(这些模块需要提前导入):
  # threading.currentThread(): 返回当前的线程变量。
  # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
'''

from  threading import Thread,current_thread,enumerate,active_count
import time

def task(name,n):
    print(f'{name}开始')
    time.sleep(n)
    print(f'{name}结束')

if __name__ == '__main__':
    t1 = Thread(target=task,args=('子线程1',1))
    t2 = Thread(target=task,args=('子线程2',2))

    l = [t1,t2]
    for t in l:
        t.start()
    print(t1.is_alive())  # 查看t1线程是否还活着  #True证明还活着
    print(t1.getName())  #获取t1线程名
    t1.setName('大猪蹄子线程')
    print(t1.getName())  #获取修改后的t1线程名
    print(current_thread())  # 返回当前线程
    print(enumerate())   #返回当前运行的线程的一个列表
    print(active_count())  #返回当前正在运行的线程数量
    t.join()
    print('主线程结束')
'''
子线程1开始
子线程2开始
True
Thread-1
大猪蹄子线程
<_MainThread(MainThread, started 13384)>
[<_MainThread(MainThread, started 13384)>, <Thread(大猪蹄子线程, started 1736)>, <Thread(Thread-2, started 10788)>]
3
子线程1结束
子线程2结束
主线程结束
'''

六、守护线程

守护线程守护的是进程的运行周期

  • 对主进程来说,运行完毕指的是主进程代码运行完毕
  • 对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
from threading import  Thread
import time

def task1():
    print('守护线程1开始')
    time.sleep(2)
    print('守护线程1结束')
    print(t1.is_alive())  #   True 当守护线程1结束了,守护线程1并没有死亡,也是在等待其他线程运行完毕

def task2():
    print('子线程2开始')
    time.sleep(3)
    print('子线程2结束')
    print(t1.is_alive())  # false 当子线程2结束了,守护线程1就死了


if __name__ == '__main__':
    t1 = Thread(target=task1)   #初始化一个对象
    t2 = Thread(target=task2)   #初始化一个对象
    t1.daemon = True  #必须在start开始之前将它设置为守护进程
    t1.start()
    t2.start()
    time.sleep(2)
    print('主线程结束')
    print(t1.is_alive())  #True  他没有因为主线程的结束而结束,而是等待子线程2运行完毕
    
'''
守护线程1开始
子线程2开始
主线程结束
True
守护线程1结束
True
子线程2结束
False
'''

七、多线程实现socket

'''服务器'''
import socket
from threading import Thread
sk_s = socket.socket()  #实例化
sk_s.bind(('127.0.0.1',8080))  #绑定
sk_s.listen(5)  #监听

def task(conn):  #子线程
    while True:  #通信循环
        msg = conn.recv(1024)   #接收线程
        conn.send(msg.upper())  #发送数据

if __name__ == '__main__':
    while True:  # 链接循环
        print('等待客户端连接>>>>')
        conn, addr = sk_s.accept()  #等待接收
        print(f'客户端{addr}连接成功')
        t = Thread(target=task,args=(conn,))  #实例化一个线程t
        t.start()  #子线程开始
'''客户端'''
import socket
sk_c = socket.socket()

sk_c.connect(('127.0.0.1',8080))

while True:
    msg = input('>>>').strip()
    if msg == "q":
        break
    msg = msg.encode('utf8')
    sk_c.send(msg)
    data = sk_c.recv(1024)
    print(data.decode('utf8'))

sk_c.close()
原文地址:https://www.cnblogs.com/yanjiayi098-001/p/11535169.html