赞
踩
每一个进程里面会有一个线程,默认的线程叫做主线程
线程是程序执行的最小单元,所有进程必须在线程中执行,默认所有代码再主线程中
跟进程的不同点是:
内存空间不一样,进程是相互独立的内存空间
线程是再同一个内存空间,可以看成是线程是进程的儿子
进程:子进程崩溃不会影响其他进程
实现硬件最大化
线程:内存空间共享,切换速度快,
创建速度快,需要极少的内存和时间
线程致命bug 全负荷工作也只是cpu核心数分之一
1,导入包
2,创建线程对象
3,启动线程
导入包
from threading import Thread
import threading
def eat():
# 打印线程名字 current_thread() 获取当前线程 线程名字是系统分配的
print('小天才喜欢吃',threading.current_thread().name)
if __name__ == '__main__':
# 获取线程的名字 threading.current_thread() 在哪个线程中执行 获取的就是哪一个线程
print('当前线程名字',threading.current_thread().name)
# 创建一个线程 target指定线程执行的任务(函数) name指定线程的名字
eat_t = Thread(target=eat,name='Rock')
# 启动线程
eat_t.start()
一个进程中的n个线程,所用的数据是共享的,两个线程对同一数据进行运算,数据会混乱.
线程锁针对于全局变量,如果是在一个线程里,那么就不用加线程锁
解决线程不安全问题,保证代码段稳定执行, 加锁就可以解决,但是代码段执行前加锁,执行后必须释放锁,否则会造成死锁.(程序出现bug,没有释放),死锁会导致锁定内容将线程black(卡住) ,解决问题, 只要保证能及时释放锁就行
线程锁
优点,
解决了线程不安全问题, 数据安全
缺点
降低程序执行的效率
1,导入锁的模块
2,加锁
3,解锁/释放
import threading
from threading import Thread
score = 100
# 线程锁
lock = threading.Lock()
def thread_one():
global score
for i in range(1000000):
# 加锁
lock.acquire()
score += 5
score -= 5
# 释放
lock.release()
def thread_two():
global score
for i in range(1000000):
lock.acquire()
score += 10
score -= 10
lock.release()
if __name__ =='__main__':
print('开始了')
t_one = Thread(target=thread_one)
t_two = Thread(target=thread_two)
t_one.start()
t_two.start()
t_one.join()
t_two.join()
print('结束了',score)
本地线程,作用是把全局变量变成局部变量,只对于一个线程有用,不影响其他线程的变量
1,导入模块
2,创建对象
3,添加
join,加在循环外部,如果加在循环内,则需要等待,一个循环完了,等待它执行完了之后,再进行下一个循环,就是单线程.
# 导入ThreadLocal
import threading
from threading import local
from threading import Thread
# 创建ThreadLocal对象
threadLocal = local()
def add_hobby(hobby):
print('添加hobby的线程 %s' % threading.current_thread().name)
# 添加hobby
threadLocal.hobby = hobby
get_hobby()
def get_hobby():
print('获取hobby的线程 %s' % threading.current_thread().name, threadLocal.hobby)
if __name__ == '__main__':
t1 = Thread(target=add_hobby,args=('eat',),name='Tommy')
t2 = Thread(target=add_hobby,args=('sleep',),name='vincent')
t1.start()
t2.start()
t1.join()
t2.join()
在线程里面发生异常,为了不影响程序的运行,一般会抛出异常,跳过这个错误,继续执行
线程执行 , 并发随机执行
线程锁,一定要释放锁,将需要加锁的模块放到try中
再finally中释放锁
主线程挂掉,主进程也会挂掉,所以,主进程会配合很多子进程进行,
主线程也会配合很多子线程进行操作,子线程一般有两步
1,获取异常,(记录错误日志Exception)
2,重启一个新进程,继续执行任务(主从结构)
import threading
# 设置锁
lock = threading.Lock()
score = 100
def eat_dump():
global score
# 操作之前加锁
lock.acquire()
# 操作
try:
score += 5
score -= 5
#获取异常
except Exception as e:
print('发生错误了 吃')
# 释放锁
finally:
lock.release()
想要让两个线程相互穿插进行,就要用到调度/礼让
礼让完了双方都在等待,这个时候需要告诉对方,你可以执行了with 开路的,就是为我们操作进行开头和扫尾的
比如,在线程中,自动加锁释放锁
在文件io中,自动关闭io流,文件读写的出入口
# 导入调度模块
from threading import Condition
# 创建调度对象
cond = Condition()
def thread_a():
# with 代替线程锁
with cond:
for i in range(0,10,2):
print(i)
# 通知对方先行
cond.notify()
# 等待礼让
cond.wait()
python中的多线程是真正的多线程
让进程开启一个线程,线程中执行一个死循环,不加优化的那种
死循环的时候, 会占用你cpu核心数的值(count) 1/count*100%
一个线程是这样,10个线程也是这样但是你使用Java,或者c,c++, 他就可以将CPU的所有资源占用
如果想实现CPU的全负荷使用,再python中需要进程和线程的配合使用
开启CPU核心数的子进程,子进程中再开启线程去干活为什么把CPU资源占满,
因为其他程序没占用,浪费资源
import threading
import time,random
# 创建信号量
# 参数为 线程限制的数量,即同时存在的线程的最大数量
sem = threading.Semaphore(3)
def run(num):
with sem:
print("%s - %d" % (threading.current_thread().name, num))
time.sleep(1)
if __name__ == '__main__':
# 创建多个线程处理数据
for i in range(20):
t =threading.Thread(target=run,args=(i,))
t.start()
规定多久后执行该线程
import threading
def func():
print("我想跟你约会")
if __name__ == '__main__':
# 创建一个延时线程,表示 该线程等待多长时间之后开始执行
# 参数1: 表示延迟的时间,单位秒,
# 参数2: 线程执行的函数
tt = threading.Timer(3,func)
tt.start()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。