多线程

1. 线程

​ 开启一个进程,操作系统会开辟一个进程空间,将进程的数据资源全部复制一份,然后cpu使线程执行代码。

进程负责开辟空间、加载数据资源,线程负责执行。

2. 线程vs进程

	1. 开启进程的开销大;
  1. 开启进程的速度满,线程比进程快10—100倍;

    3. 同一进程的线程之间可共享数据,进程与进程之间使隔离的。

线程的应用:多线程并发。比多进程并发开销小、速度快,可共享数据。

3. 开启线程的两种方法。

# 第一种方式
from threading import Thread def task():
print("===子线程") if __name__ == '__main__': # 在windows下也可不写
t1 = Thread(target=task)
t1.start()
print('===主线程')
"""
===子线程
===主线程
"""
# 第二种方式
from threading import Thread class MyThread(Thread): def __init__(self, name)
super().__init()
self.name=name def run(self):
print("==={self.name}子线程") if __name__ == '__main__':
t1 = MyThread("meet")
t1.start()
print('===主线程')
"""
===meet子线程
===主线程
"""

4. 线程的特性

  1. 同一进程中,每个线程的pid相同,因为它们在同一进程内。
  2. 主线程需等待其他子线程结束后,才能结束。(因为主线程结束代表本进程结束,而子线程需依赖进程存活。)
  3. 同一进程内的数据资源对于本进程的多个进程来说是共享的。

5. 线程的相关方法

Thread实例对象方法:
t.is_alive()(t.isAlive()) #判断线程是否活着
t.getName() # 获取线程名
print(t.name) # 获取线程名
t.setName() # 设置线程名 threading模块方法:
currentThread() # 获取当前线程的对象
enumerate() # 获取进程中所有线程对象,返回列表
activeCount() # 获取活跃的线程数量
from threading import Thread,currentThread,enumerate,activeCount
import time def task():
time.sleep(1)
print("is task") if __name__ == '__main__':
t1 = Thread(target=task,name='===子线程')
t1.start()
print(t1.name) # ===子线程
print(t1.is_alive()) # True
t1.setName('子线程')
print(t1.getName()) # 子线程 print(currentThread()) #主线程对象
print(enumerate()) # 列表中两个线程对象
print(activeCount()) # 2
print('===主线程')
"""
True
子线程
<_MainThread(MainThread, started 14876)>
[<_MainThread(MainThread, started 14876)>, <Thread(子线程, started 8736)>]
2
===主线程
is task
"""

6. join 阻塞

​ 告知主线程需等待子线程执行结束后,再开始执行。

from threading import Thread
import time
def sayhi(name):
time.sleep(2)
print('%s say hello' %name) if __name__ == '__main__':
t=Thread(target=sayhi,args=('meet',))
t.start()
t.join()
print(t.is_alive())
print('主线程')
'''
meet say hello
False
主线程
'''

7. 守护线程 daemon

若主线程运行结束,守护线程也会跟着结束。

对主线程来说,运行完毕指的是本进程内所有非守护线程统统运行完毕,主线程才算运行完毕(若守护线程的生命周期小于其他的线程,会先结束)。

from threading import Thread
import time def foo():
print(123)
time.sleep(3)
print("end123") def bar():
print(456)
time.sleep(1)
print("end456") if __name__ == '__main__':
t1=Thread(target=foo)
t2=Thread(target=bar)
t1.daemon=True # 设置t1为守护进程
t1.start()
t2.start()
print("main---")
"""
123
456
main---
end456
"""
# 面试题---迷惑人的例子
from threading import Thread
import time def foo():
print(123) # 1
time.sleep(1)
print("end123") # 4 def bar():
print(456) # 2
time.sleep(2)
print("end456") # 5 if __name__ == '__main__': t1=Thread(target=foo)
t2=Thread(target=bar)
t1.daemon=True # 设置t1为守护进程
t1.start()
t2.start()
print("main-------") # 3 """
123
456
main---
end123
end456
"""
# 因为bar需2s执行完毕,2s足够守护进程的foo执行完毕。因此在主线程结束前,守护线程以及结束。

8. 互斥锁

​ 多线程的同步锁与多进程的同步锁是一个道理,就是多个线程抢占同一个数据(资源)时,我们要保证数据的安全,合理的顺序,因此需串行。

from threading import Thread
from threading import Lock
import time
import random x = 100 def task(lock):
global x
lock.acquire()
num = x
time.sleep(random.random())
x = num-1
lock.release() if __name__ == '__main__':
mutex = Lock()
for i in range(100):
t = Thread(target=task, args=(mutex,))
t.start()
time.sleep(2)
print(f'主线程{x}') # 输出不固定 串行执行

python 35 多线程的更多相关文章

  1. Python的多线程(threading)与多进程(multiprocessing )

    进程:程序的一次执行(程序载入内存,系统分配资源运行).每个进程有自己的内存空间,数据栈等,进程之间可以进行通讯,但是不能共享信息. 线程:所有的线程运行在同一个进程中,共享相同的运行环境.每个独立的 ...

  2. Python GIL 多线程机制 (C source code)

    最近阅读<Python源码剖析>对进程线程的封装解释: GIL,Global Interpreter Lock,对于python的多线程机制非常重要,其如何实现的?代码中实现如下: 指向一 ...

  3. Python实现多线程HTTP下载器

    本文将介绍使用Python编写多线程HTTP下载器,并生成.exe可执行文件. 环境:windows/Linux + Python2.7.x 单线程 在介绍多线程之前首先介绍单线程.编写单线程的思路为 ...

  4. Python实现多线程调用GDAL执行正射校正

    python实现多线程参考http://www.runoob.com/python/python-multithreading.html #!/usr/bin/env python # coding: ...

  5. Python之多线程和多进程

    一.多线程 1.顺序执行单个线程,注意要顺序执行的话,需要用join. #coding=utf-8 from threading import Thread import time def my_co ...

  6. python的多线程到底有没有用?

    在群里经常听到这样的争执,有人是虚心请教问题,有人就大放厥词因为这个说python辣鸡.而争论的核心无非就是,python的多线程在同一时刻只会有一条线程跑在CPU里面,其他线程都在睡觉.这是真的吗? ...

  7. 通过编写聊天程序来熟悉python中多线程及socket的用法

    1.引言 Python中提供了丰富的开源库,方便开发者快速就搭建好自己所需要的应用程序.本文通过编写基于tcp/ip协议的通信程序来熟悉python中socket以及多线程的使用. 2.python中 ...

  8. Python的多线程和多进程

    (1)多线程的产生并不是因为发明了多核CPU甚至现在有多个CPU+多核的硬件,也不是因为多线程CPU运行效率比单线程高.单从CPU的运行效率上考虑,单任务进程及单线程效率是最高的,因为CPU没有任何进 ...

  9. Python【多线程与多进程】

    import time,threading print("=======串行方式.并行两种方式调用run()函数=======")def run(): print('哈哈哈') # ...

随机推荐

  1. [PTA] 1002. 写出这个数 (Basic)

    import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Sc ...

  2. SCADA开源项目lite版本

    一.引子 自从看了老坏猫(江湖人称猫总)的SharpSCADA项目后,让我感觉耳目一新同时也对自动化数据采集有了更深入的认识,我相信有不少做上位机的朋友和我一样对这个项目非常好奇.我们做上位机的应用场 ...

  3. 转 java - java基础知识点

    转 https://www.cnblogs.com/xdp-gacl/p/3641769.html 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可 ...

  4. Redis项目实战---应用及理论(上)---redis基础知识介绍

    redis(Remote Dictionary Server)   一.原理及特性层面:     1.优势:        1)数据加载在内存中,执行速度快, 数据结构类似于HashMap,HashM ...

  5. CSS布局定位基础-盒模型和定位机制

    1. 盒模型 2. 外边距合并 3. 定位机制 4. Float 5. Position:属性有哪些取值,它们的行为是什么? 无依赖绝对定位? 6. Display:常见属性值有哪些取值? 7. 对B ...

  6. StringBuffer类的delete()方法和deleteCharAt()方法的区别

    引言 StringBuffer类的delete()方法和deleteCharAt()方法都是用来删除StringBuffer字符串中的字符 区别 1.对于delete(int start,int en ...

  7. Android Studio项目/Flutter 案例中Gradle报错通用解决方案(包括Unable to tunnel through proxy问题)

    目录 Step 1:修改Gradle版本为本地版本 Step 2:修改classpath为Android Studio版本 Step 3:关闭代理 Step 1:修改Gradle版本为本地版本     ...

  8. 七分钟理解什么是 KMP 算法

    本文是介绍 什么是 BF算法.KMP算法.BM算法 三部曲之一. KMP算法 内部涉及到的数学原理与知识太多,本文只会对 KMP算法 的运行过程. 部分匹配表 .next数组 进行介绍,如果理解了这三 ...

  9. Java内存模型的基础

    Java内存模型的基础 并发编程模型的两个关键问题 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在 ...

  10. python基础之循环与迭代器

    循环 python 循环语句有for循环和while循环. while循环while循环语法 while 判断条件: 语句 #while循环示例 i = 0 while i < 10: i += ...