标签:txt ali str 定时器 net access 线程 的区别 代码
程序在运行代码的过程。
进程:一个在运行中的程序(具体内容是由线程来运行)的状态,是系统的一个资源单位。
线程:运行指定代码的过程。一个进程中至少有一个线程,但是一个进程可以有多个线程。线程是cpu调度的最小单位。
类比到现实中就是生产车间(指代进程)与流水线(指代线程)的关系。我们可以说这个车间是生产汽车,生产车间里面的每一条流水线都是生产汽车部件的。生产车间是由一个一个流水线组合成地。进程也是由线程构成地。
使用threading模块创建Thread,而且创建线程的方式与multiprocessing创建线程的方式一样(据说是multiprocessing照着threading写的,不要说是我说的)
方式一:实现Thread类
from threading import Thread,currentThread
def pr():
print(f'我是进程{currentThread().name}!')
t = Thread(target=pr)
t.start()
print('我是主进程!')
#######################
# 结果:
我是进程Thread-1! # 因为创建线程的速度很快所以创建了线程就执行了代码
我是主进程!
方式二:继承Thread类
from threading import Thread,currentThread
class MyT(Thread):
def run(self) -> None: # 必须重写run方法
print(f'我是进程{currentThread().name}')
t = MyT()
t.start()
print('我是主进程!')
#######################
# 结果:
我是进程Thread-1!
我是主进程!
join
主线程等待子线程运行结束
from threading import Thread
import time
def task():
print('子线程开启!')
time.sleep(2)
print('子线程结束!')
t = Thread(target=task)
t.start()
print('主线程结束!')
######################
# 结果:
子线程开启!
主线程结束!
子线程结束!
isAlive()
线程是否还在运行
from threading import Thread
import time
def task():
print('子线程开启!')
time.sleep(2)
print('子线程结束!')
t = Thread(target=task)
t.start()
time.sleep(1)
print(t.isAlive()) # True
print('主线程结束')
getName()
获取线程名字
from threading import Thread
import time
def task():
print('子线程开启!')
time.sleep(2)
print('子线程结束!')
t = Thread(target=task)
t.start()
print(t.getName()) # Thread-1
print('主线程结束')
setName()
设置线程名字
from threading import Thread
import time
def task():
print('子线程开启!')
time.sleep(2)
print('子线程结束!')
t = Thread(target=task)
t.start()
print(t.getName()) # Thread-1
t.setName('张三')
print(t.getName()) # 张三
print('主线程结束')
currentThread()
获取当前线程对象
from threading import Thread,currentThread
import time
def task():
print(currentThread().getName()) # Thread-1
currentThread().setName('张三')
print(currentThread().getName()) # 张三
t = Thread(target=task)
t.start()
time.sleep(0.5)
print(t.getName()) # 张三
print('主线程结束')
enumerate()
返回当前活动进程
from threading import Thread,enumerate
import time
def task():
print('子线程开启!')
time.sleep(2)
print('子线程结束!')
t = Thread(target=task)
t.start()
print(enumerate()) # [<_MainThread(MainThread, started 3068)>, <Thread(Thread-1, started 16348)>]
print('主线程结束')
activeCount()
返回当前活动线程数量
from threading import Thread,activeCount
import time
def task():
print('子线程开启!')
time.sleep(2)
print('子线程结束!')
t = Thread(target=task)
t.start()
print(activeCount()) # 2
print('主线程结束')
守护线程守护至当前进程结束
from threading import Thread
import time
def task():
print('子线程开启!')
time.sleep(2)
print('子线程结束!')
t = Thread(target=task)
t.daemon = True
t.start()
print('主线程结束')
但是,主进程会等待还没有结束的子线程结束后结束
from threading import Thread
import time
def task():
print('守护线程开启!')
time.sleep(2)
print('守护线程结束!')
def pr():
print('子线程开启!')
time.sleep(3)
print('子线程结束!')
t = Thread(target=task)
t.daemon = True
t.start()
t = Thread(target=pr)
t.start()
print('主线程结束')
当我们要对线程间共享的资源进行操作,为了资源的安全考虑,就需要为资源加上线程锁。这样就可以保证同一个资源同一时刻只有一个线程有权限去修改。
from threading import Lock,Thread
import time
#初始化一把锁,由于线程间共享内存所以可以不用传递参数
lock=Lock()
count = 1
def buy():
#获取钥匙在acquire()和release()之间的代码在同一时间只允许一个进程执行,当一个进程完成后将钥匙归还后,其他的进程才可以获得钥匙。
lock.acquire() # 拿锁
# 模拟网络的延迟
global count
time.sleep(0.1)
if count>0:
print('买到票了')
count=count-1
with open('access.txt', 'w', encoding='utf-8') as f:
f.write(str(count))
else:
print('没票了')
lock.release() #还锁
count = 1
for i in range(5):
p=Thread(target=buy)
p.start()
当程序中有两把锁,并且一个线程需要拿到两把锁才能运行下去的时候,就会发生死锁的问题
from threading import Lock,Thread,currentThread
import time
lock1 = Lock()
lock2 = Lock()
def func1():
lock2.acquire()
print('\033[41m%s 拿到A锁\033[0m' % currentThread().name)
lock1.acquire()
print('\033[42m%s 拿到B锁\033[0m' % currentThread().name)
lock1.release()
lock2.release()
def func2():
lock1.acquire()
print('\033[43m%s 拿到B锁\033[0m' % currentThread().name)
time.sleep(2)
lock2.acquire()
print('\033[44m%s 拿到A锁\033[0m' % currentThread().name)
lock2.release()
lock1.release()
t1 = Thread(target=func2)
t2 = Thread(target=func1)
t1.start()
t2.start()
解决死锁问题可以使用 递归锁
在一个线程中是的锁可以被多次获取,但是不同线程间只能有一个线程获得锁
from threading import RLock,Thread,currentThread
import time
lock1 = RLock()
lock2 = lock1
def func1():
lock2.acquire()
print('\033[41m%s 拿到A锁\033[0m' % currentThread().name)
lock1.acquire()
print('\033[42m%s 拿到B锁\033[0m' % currentThread().name)
lock1.release()
lock2.release()
def func2():
lock1.acquire()
print('\033[43m%s 拿到B锁\033[0m' % currentThread().name)
time.sleep(2)
lock2.acquire()
print('\033[44m%s 拿到A锁\033[0m' % currentThread().name)
lock2.release()
lock1.release()
t1 = Thread(target=func2)
t2 = Thread(target=func1)
t1.start()
t2.start()
因为cpython自带的垃圾回收机制不是线程安全的,所以要有GIL锁来保证同一时间只有一个线程在解释器中运行。但是这会导致cpython中的多线程并不是真正意义上的多线程,它只能运用到单核的性能。
解决这个问题主要有两种办法:
具体可以看:https://blog.csdn.net/IAlexanderI/article/details/72932309
队列
先进先出
import queue
q = queue.Queue()
q.put('123')
q.put('qweqwe')
print(q.get())
print(q.get())
###############
# 结果:
123
qweqwe
栈
后进先出
import queue
q = queue.LifoQueue()
q.put('123')
q.put('qwe')
q.put('asd')
print(q.get())
print(q.get())
print(q.get())
################
# 结果:
asd
qwe
123
优先级
按照元组中的优先级输出
import queue
q = queue.PriorityQueue()
q.put((4,'123'))
q.put((2,'qwe'))
q.put((3,'asd'))
print(q.get())
print(q.get())
print(q.get())
################
# 结果:
(2, 'qwe')
(3, 'asd')
(4, '123')
倒计时,当时间归零开始执行线程
from threading import Timer
def task():
print('线程开始执行')
t = Timer(4,task) # 过了4s后开启了一个线程
t.start()
标签:txt ali str 定时器 net access 线程 的区别 代码
原文地址:https://www.cnblogs.com/Gredae/p/11570308.html