多线程

多线程的创建

import threading
def func(arg):
    print(arg)

t1 = threading.Thread(target=func,args=(333,))  #创建一个线程t1, args后跟的是一个元组
t1.start()

t2 = threading.Thread(target=func,args=(111,))  #创建一个线程t1
t2.start()

线程的基本使用

import threading

def func(arg):
    print(arg)

t = threading.Thread(target=func,args=(123,))
t.start()
print(1111)

# 结果:
# 123
# 1111

线程的本质

import threading
def func(arg):
    print(arg)

t1 = threading.Thread(target=func,args=(111,))
t1.start()  
#start 是开始运行线程吗? 不是的. 主要是告诉CPU,已经准备就绪,可以调用

print(123)

先打印111 还是先打印123 不确定
如果一个进程下面有3个线程, 一个是主线程 111, 一个是子线程123, cpu正在执行第三个线程
这就很难判断cpu 下一步是执行111, 还是123, 从打印的结果看不出来的

主线程默认等子线程执行完毕

import threading
import time

def func(arg):
    time.sleep(arg)
    print(arg)

t1 = threading.Thread(target=func,args=(2,))
t1.start()

t2 = threading.Thread(target=func,args=(4,))
t2.start()

print(1234)
# 结果
# 1234
# 2
# 4

主线程不等待子线程的情况, 主线程执行完毕后, 子线程就停止

import time
import threading

def func(arg):
    time.sleep(arg)
    print(arg)
t1
= threading.Thread(target=func,args=(4,)) t1.setDaemon(True) # True 主线程 执行完毕不等 子线程 t1.start() t2 = threading.Thread(target=func,args=(2,)) t2.setDaemon(False) # False 主线程等待子线程执行完毕
# 线程2 如果停顿时间比 线程1 短的时候,就会只执行 线程2
t2.start() print(1111111) # 结果 # 1111111 # 2
def func(arg):
    time.sleep(arg)
    print(arg)
t1 = threading.Thread(target=func,args=(4,))
t1.setDaemon(True)         # True 主线程 执行完毕不等 子线程 t1
t1.start()

t2 = threading.Thread(target=func,args=(6,))      
t2.setDaemon(False)    # False 主线程等待子线t2 程执行完毕
#线程2如果停顿时间参数arg比线程1的时间长,在等待t2的时候,线程t1还在运行,所以t1还是会被打印

t2.start()
print(1111111) # 结果 # 1111111 # 4 # 6

开发人员可以控制主线程等待子线程的时间(最长等待时间)

import threading
import time

def func(arg):
    time.sleep(2)
    print(arg)

print("创建子线程t1")
t1 = threading.Thread(target=func,args=(3,))
t1.start()
t1.join()     #无参数,让主线程在这里等待,等子线程t1执行完毕后,才可以继续往下走
# t1.join(2)  #有参数,让主线程在这里最多停留n 秒,无论是否执行完毕都会继续往下走

print("创建子线程t2")
t2 = threading.Thread(target=func,args=(6,))
t2.start()
t2.join(1)    #让主线程在这等1秒后才打印1234, 如果子线程睡了0.5秒, 就只等待0.5秒. 1是最多等待1秒

print(1234)
#结果
创建子线程t1
3
创建子线程t2
1234
6

获取线程的名称

import threading
def func(arg):

    # 获取当前执行该函数的线程对象
    t = threading.current_thread()

    # 根据当前线程对象获取当前线程名称
    name = t.getName()
    print(name,arg)

t1 = threading.Thread(target=func,args=(11,))
t1.setName("王小二")
t1.start()

t2 = threading.Thread(target=func,args=(22,))
t2.setName("张三")
t2.start()
print(1234)

# 王小二 11
# 张三 22
# 1234

GIL全局解释器锁

python内置的一个全局解释器锁,同一时刻的进程中,只有一个线程被cpu调用.

也可以这么理解,

软件就是一个进程(宫殿),  进程就创建一个空间(宫殿), 进程里面可以有多个线程(妃子)

GIL锁限制一个进程(宫殿)中只有一个线程(妃子),可以被cpu(皇上)调用

如果一个进程里面有多个线程,cpu就会在多个线程之间来回调用,执行的速度很快,人感觉不到停顿.

但是中间到底停留了多久呢?

import sys

v1 = sys.getcheckinterval()
print(v1)   #100
默认GIL锁使得每一线程处理100个cpu指令以后,会切换到下一个线程
GIL锁(全局解释器锁),限制一个进程(宫殿)中只有一个线程(妃子), 可以被CPU(皇上)调用
原文地址:https://www.cnblogs.com/kenD/p/9628181.html