线程的开启方法

进程是操作系统调度的最小单位,一个进程最少有一个主线程,而一个进程中可以开启多个线程

from threading import Thread

def task():
print('A child thread') if __name__ == '__main__': # 这里是可以不用写的,但是规范起见还是写了
t = Thread(target=task)
t.start()
print('==>main thread')

GIL锁

"""

 1. Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行
2. Python 解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行。 1、GIL锁它是在python解释器中的, 只在cpython中有, pypy解释器是没有GIL锁的,
2、起一个垃圾回收线程, 一个是正常执行的线程
3、设置了一把锁(GIL锁), 一个线程要想执行,必须拿到这把锁
4、同一时刻,开启一个进程,一个进程中可以有多个线程, 只能有一个线程在执行 5、如果是计算密集型:要开进程
6、如果是io密集型:要开线程
"""

进程与线程的比较

线程与进程的区别可以归纳为以下4点:

  1. 地址空间和其它资源(如打开文件):进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
  2. 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
  3. 调度和切换:线程上下文切换比进程上下文切换要快得多。
  4. 在多线程操作系统中,进程不是一个可执行的实体。

进程消耗的资源比线程要大的多,相对的,调用起来也比线程要慢

# 进程调用时间演示
import time
from multiprocessing import Process def task():
time.sleep(1)
print('A child process') if __name__ == '__main__':
start = time.time()
p = Process(target=task)
p.start()
p.join()
print('master process')
print(time.time() - start) # 输出结果
# A child process
# master process
# 1.069324016571045
# 线程调用时间演示
import time
from threading import Thread def task():
time.sleep(1)
print('A child thread') if __name__ == '__main__':
start = time.time()
t = Thread(target=task)
t.start()
t.join()
print('==>main thread')
print(time.time()-start)
# 输出结果
# A child thread
# ==>main thread
# 1.005803108215332

线程间的数据是共享的

def task():
global n
n=0 if __name__ == '__main__':
n=1
t=Thread(target=task)
t.start()
t.join()
print('主',n) # 查看结果为0,因为同一进程内的线程之间共享进程内的数据

Thread类的方法

t.is_alive() # 返回线程是否活动
t.getName() # 获取线程名
t.setName() # 更新线程名
threading.currentThread() # 返回当前的线程变量
threading.enumerate() # 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程
threading.activeCount() # 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果

守护线程

from threading import Thread
import time
def task():
time.sleep(1)
print("我是子线程") if __name__ == '__main__':
t = Thread(target=task,)
t.setDaemon(True) # 开启守护线程, 主线程结束,子线程跟着结束
t.start() print("主线程")

线程互斥锁

from threading import Thread,Lock
import time
import random def task(lock):
#上锁
lock.acquire()
global n
# 10个线程同时涌入导致数据不安全
time.sleep(random.random())
n -= 1
# 释放锁
lock.release() if __name__ == '__main__':
start = time.time()
lock = Lock()
n = 100
l = []
for i in range(10):
t = Thread(target=task,args=(lock,))
t.start()
l.append(t)
for j in l:
j.join()
print('运算完毕:n = %s' %n)
print(time.time()-start)

信号量

from threading import Thread,Semaphore
import time def task(i, sm):
# 上锁
sm.acquire()
print("%s:这个人开始上厕所了" % i)
time.sleep(3)
print("%s:这个人上完了" % i)
# 释放锁
sm.release() # Semaphore:信号量可以理解为多把锁,同时允许多个线程来更改数据
if __name__ == '__main__':
sm = Semaphore(2) #
for i in range(10):
t = Thread(target=task, args=(i, sm))
t.start()

Event事件

from threading import Thread, Event

import time

def girl(event):
print("都女士正在恋爱中...")
time.sleep(3)
print("都女生分手了") # 发出分手的信号
event.set() def boy(i, event):
print("渣男:%s正在等待都女生分手" % i)
# 卡住
event.wait()
print("渣男:%s开始追了" % i) if __name__ == '__main__':
event = Event() t = Thread(target=girl, args=(event,))
t.start() for i in range(10):
b_t = Thread(target=boy, args=(i, event))
b_t.start()

释放出信号,而读数据课以收信号,一旦示范出可以读的信号该线程才会运行

最新文章

  1. 开始研究web,mark一下
  2. 不封装ajax 带url参数调用接口
  3. Mac使用wireshark对移动设备抓包
  4. distributed caching for .net applications
  5. AngularJS 学习之表格
  6. linux下开启mysql慢查询,分析查询语句
  7. 学习练习 java面向对象存取款查询余额
  8. android 19 activity纵横屏切换的数据保存与恢复
  9. 防止tab页重复的去请求服务端
  10. centOS7 mini配置linux服务器(一)安装centOs7
  11. pycharm安装和首次使用
  12. Nginx的安装(笔记)
  13. 腾讯云服务器web环境配置过程
  14. tuple的基本使用
  15. EDK II之Device Path
  16. [UE4]Input Key Selector
  17. POJ - 3080 Blue Jeans 【KMP+暴力】(最大公共字串)
  18. 通过Word 2016 发布的内容
  19. xslt 简单的语法
  20. Mybatis的枚举处理器

热门文章

  1. PHP利用百度ai实现文本和图片审核
  2. RSTP_PA协商过程
  3. python使用笔记14--商品管理小练习
  4. 禅道项目管理软件-Linux上一键安装
  5. 交换机H3C S3100V2-52TP-WiNet
  6. SOA-面向服务的架构
  7. Java基础00-反射35
  8. Java基础00-方法引用32
  9. 【开发工具】-- IDEA集成Git在实际项目中的运用
  10. 以太坊-Mac环境下remix环境搭建