并发编程—线程

1. 线程

1.1 什么是线程

在操作系统中,每个进程都有一个地址空间, 且默认有一个控制线程,cpu真正的执行单位是线程。

如果把操作系统比作工厂,那么进程就是车间,每个车间里都有流水线,即进程,流水线都需要电源驱动,这个电源就是CPU 。

1.2 线程与进程区别

  • 过程的区别

    线程:代码的执行过程

    进程:资源的申请与销毁,是资源的整合

  • 内存空间的区别

    进程:内存空间彼此隔离

    线程:同一进程下的多个线程共享资源

  • 创建速度

    进程:需要申请资源,开辟空间,速度较慢

    线程:只是告诉操作系统一个执行方案,速度很快、

1.3 开启线程的两种方式

  • 方式一(推荐)

    from threading import Thread
    
    
    def task():
        print("子线程")
        
    t = Thread(target=task)
    t.start()
    
  • 方式二

    from threading import Thread
    
    
    class MyThread(Thread):
        def run(self):
            print("子线程")
            
    
    t = MyThread()
    t.start()
    

1.4 线程与进程的区别(开启速度与内存空间)

  • 开启速度

    # 进程开启速度
    import time
    from multiprocessing import Process
    
    def task():
        print('子进程开始')
        time.sleep(2)
        print('子进程结束')
        
    if __name__ == '__main__':
        p = Process(target=task)
        p.start()
        print('主进程')
    
    # 执行结果
    主进程
    子进程开始
    子进程结束
    
    # 线程开启速度
    import time
    from threading import Thread
    
    
    def task():
        print('子线程开始')
        time.sleep(2)
        print('子线程结束')
        
        
    t = Thread(target=task)
    t.start()
    print('主线程')
    
    # 执行结果
    子线程开始
    主线程
    子线程结束
    

    总结:进程开启后需要申请资源,开辟内存空间,速度较慢

    ​ 线程开启后CPU只需执行线程代码,速度很快

  • 内存空间

    from threading import Thread
    
    x = 0
    def task():
        global x
        x = 1
        
    t = Thread(target=task)
    t.start()
    print(x)		# 1
    

    总结:进程:内存空间彼此隔离,进程间通信需要IPC方式,即使用磁盘或内存通信

    ​ 线程:同一进程下的线程共享同一内存空间,共享这块空间内的所有资源

1.5 线程的join用法

  • t.join:阻塞,等待线程t结束后继续往下执行
import time
from threading import Thread

def task():
    print('子线程开始')
    time.sleep(2)
    print('子线程结束')
    
    
t = Thread(target=task)
t.start()
t.join()		# 阻塞,等待子线程结束
print('主线程')
# 执行结果
子线程开始
子线程结束
主线程
# 多个join的运行结果
import time
from threading import Thread


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

start = time.time()
t1 = Thread(target=task, args=('子线程1', 1))
t2 = Thread(target=task, args=('子线程2', 2))
t3 = Thread(target=task, args=('子线程3', 3))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
end = time.time()
print(end - start)		# 3s多一点点

1.6 线程的其他方法

  • currentThread:当前所在线程
  • enumerate:当前所有线程
  • activeCount:当前线程数量
import time
from threading import Thread, currentThread, enumerate, activeCount


def task():
    print('子线程开始')
    time.sleep(2)
    print('子进程结束')import time
from threading import Thread, currentThread, enumerate, activeCount


def task():
    print('子线程开始')
    time.sleep(2)
    print('子进程结束')
    print(currentThread())		# 当前所在线程 <Thread(Thread-1, started 23360)>
    print(enumerate())		# 当前所有的线程 [<_MainThread(MainThread, stopped 2664)>, <Thread(Thread-1, started 23360)>]


t = Thread(target=task)
t.start()
print(currentThread())	# 当前所在线程 <_MainThread(MainThread, started 2664)>
print(enumerate())		# 所有的线程 [<_MainThread(MainThread, started 2664)>, <Thread(Thread-1, started 23360)>]
print(activeCount())		# 当前的线程数量 2
# 运行结果
子线程开始
<_MainThread(MainThread, started 2664)>
[<_MainThread(MainThread, started 2664)>, <Thread(Thread-1, started 23360)>]
2
子进程结束
<Thread(Thread-1, started 23360)>
[<_MainThread(MainThread, stopped 2664)>, <Thread(Thread-1, started 23360)>]

1.7 守护线程

守护线程:守护进程的运行周期,即进程结束时(进程内所有线程与子进程都结束)守护线程也结束

import time
from threading import Thread
from multiprocessing import Process


def daem():
    print('守护线程开始')
    time.sleep(10)
    print('守护线程结束')


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


def task2():
    print('子进程开始')
    time.sleep(5)
    print('子进程结束')


if __name__ == '__main__':
    p = Process(target=task2)
    p.start()
    d = Thread(target=daem)
    t = Thread(target=task)
    d.daemon = True
    d.start()
    t.start()
    print('主线程')
# 执行结果
守护线程开始
主线程
子线程开始
子进程开始
子线程结束
子进程结束
posted @ 2019-09-17 19:04  油饼er  阅读(86)  评论(0编辑  收藏  举报