线程的概念

1.线程的介绍

在Phon中,想要实现多任务除了使用进程,还可以使用线程来完成,线程是实现多任务的另外一种方式,线程是使用资源的最小单元,依附于进程

2.线程的概念

线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度·也就是说
线程是cpu调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程

3.线程的作用

程序启动后默认会有一个主线程,程序员自己创建的线程可以称为子线程,多线程可以完成多个任务,需要用CPU调度来完成

4.单线程和多线程

做个简单的比喻:进程=火车,线程=车厢
线程在进程下行进(单纯的车厢无法运行)
一个进程可以包含多个线程(一辆火车可以有多个车厢)不同进程间数据很难共享
(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)
同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)
进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)进程间不会相互影响,
一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,
将影响到所有车厢)进程可以拓展到多机,
进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)进程使用的内存地址可以上锁
,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。
(比如火车上的洗手间)
-"互斥锁"进程使用的内存地址可以限定使用量
(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”


5.多线程(多任务实现的方式)

1 import threading
2 threading.Thread(target = xxx)
3 start()

6.线程执行带有参数的任务

import threading

def dance(count):
    for i in range(count):
        print('跳舞',i)


if __name__ == '__main__':
    #带有参数的函数:
    #args:元组
    #kwargs:字典

    my_dance = threading.Thread(target=dance,args=(5,))
    # my_dance = threading.Thread(target=dance, kwargs={"nums":6})

    my_dance.start()

7.线程的注意点介绍

1.线程之间执行是无序的
2.主线程会等待所有的子线程执行结束再结束
3.线程之间共享全局变量
4.线程之间共享全局变量数据出现错误问题

8.守护线程

守护主线程:
·守护主线程就是主线程退出子线程销毁不再执行
	设置守折主线程有两种方式
1. threading Thread(target=show_info, daemon=True)
2. 线程对象.setDaemon(True)


示例代码:
import threading
import time

def show_info():
    for i in range(5):
        print('test',i)
        time.sleep(0.5)


if __name__ == '__main__':
    #创建子线程守护主线程,让子线程随着主线程的结束而结束
    
    #daemon=True守护主线程
    #守护主线程方式1
    sub_thread = threading.Thread(target=show_info,daemon=True)
    #设置成为守护主线程,主线程退出后子线程直接销毁不再执行子线程的代码
    
    #方式2  对象.setDaemon(True)
    sub_thread = threading.Thread(target=show_info)
    sub_thread.setDaemon(True)
    
                                  
    sub_thread.start()
    time.sleep(1)
    print('over')

9.线程共享全局变量

import threading

g_num = 0


def sum_num1():
    global g_num
    # for 循环让值最终加到100000
    for i in range(100000):
        g_num += 1
    print("sum_num1:",g_num)

def sum_num2():
    global g_num
    # for 循环让值最终加到100000  
    for i in range(100000):
         g_num += 1
    print("sum_num2:", g_num)


if __name__ == '__main__':
    sub_num1 = threading.Thread(target=sum_num1)
    sub_num2 = threading.Thread(target=sum_num2)

    sub_num1.start()
    sub_num2.start()

10.互斥锁

线程同步的方式:
1.线程等待(join)  = 第一个线程执行完毕后再执行第二个线程,即同一时刻只能执行一个任务
2.互斥锁 = 对共享数据进行锁定,保证同一时刻只能有一个线程去操作,第一个线程先执行,没有执行的线程需要等待,等互斥锁使用完释放后,其他线程再一个个去执行threading模块中定义了Lock 变量 ,这个变量本质就是个函数,通过调用这个函数就可以获取一把互斥锁互斥锁使用步骤:
#创建锁  写在全局里my_lock = threading.Lock()
#上锁    
写在函数内部上方my_lock.acquire()
#释放锁  
写在函数内部下方my_lock.release()
注意点· acquire和 release方法之间的代码同一时刻只能有一个线程去操作· 
如果在调用 acquire方法的时候其他线程已经使用了这个互斥锁,那么此时 acquire方法会堵塞,直到这个互斥锁释放后才能再次上锁
posted @ 2021-07-21 21:29  Aisa  阅读(451)  评论(0)    收藏  举报