进程与线程

1.进程:计算机程序只是存储在磁盘中的可执行二进制(或其他类型)的文件。只有把他们加载到内存中并被操作系统调用,才具有其生命周期。进程则是一个执行中的程序。每个进程都拥有自己的地址空间,内存,数据栈以及其他用于跟踪执行的辅助数据。进程也可以通过派生新的进程来执行其他任务。由于每个进程有自己的数据,所以只能采用进程间通信(IPC)的方式来共享信息。

2.线程:又称轻量级进程。一个进程开始便会创建一个线程,称为主线程。一个进程可以创建多个线程,多线程即是同一进程下的不同执行路径,同一进程下的线程共享该进程的数据区。线程以并发的方式执行,线程执行时可以被中断和挂起。(在多核cpu中,多线程才可能并行执行)

图解多线程与单线程:单核与多核

        

线程和python

1.全局解释器锁

python代码执行是由python虚拟机(又称解释器主循环)控制的。python在主循环中同时只能有一个控制线程在执行,就像单核cpu系统中,内存中可以有很多程序,但任意给定时刻只能有一个程序在运行。同理,尽管python解释器可以运行多线程,但在任意给定时刻只有一个线程会被解释器执行。

对python虚拟机由全局解释器锁(GIL)控制。正是由于GIL的存在,python解释器在某一时刻只能让一个线程执行。多线程执行方式如下:

1)设置GIL

2)切换一个线程去执行

3)执行下面操作之一

  a.指定数量字节码指令

  b.线程让出控制权

4)线程设置成睡眠(挂起)状态

5)解锁GIL

6)重复1-5

2.python多线程的作用,原理,缺陷

作用:提高程序执行速度。

原理:多线程能够提高执行速度的原因是什么?假如一个程序包含多个子任务,这些任务相互独立,没有因果关系。

a.单线程情况下,执行过程中,某个子任务在等待I/O,然而I/O到来的时间不确定,cpu时间耗在毫无意义的等待上,程序执行时间也将加上这一段等待的时间。

b.多线程情况下,若某个子任务等待I/O,可切换出其他线程执行,等到合适的时机(I/O到达)再切换回该线程,避免了cpu无意义的等待,也降低了程序的执行时间。

缺陷:由于GIL的存在,python多线程中只能有一个线程会被执行,因而无法利用多核cpu能够实现并行执行的特点。不仅如此,由于线程的切换需要时间开销,多线程使用不当的程序执行速度还可能要慢于单线程程序执行的速度。

3.python多线程的使用场合

I/O密集型应用

_thread模块

python的_thread模块提供了基本的线程和互斥锁支持,threading模块则提供了功能更全面的线程管理。以下讨论_thread模块

主要方法

_thread.start_new_thread(function,args,kwargs=None)    //派生一个新的线程,给定agrs和kwargs来执行function

_thread.allocate_lock()  //分配锁对象

_thread.exit()  //线程退出

lock.acquire(waitflag=1, timeout=-1)  //获取锁对象

lock.locked()  //如果获取了锁对象返回true,否则返回false

lock.release()  //释放锁

其他方法

_thread.LockType()  //锁对象类型

_thread.get_ident()  //获取线程标识符

-thread.TIMEOUT_MAX  //lock.acquire的最大时间,超时将引发OverflowError

_thread.interrupt_main()  //引发主线程KeyboardInterrupt错误,子线程可以用这个函数来终止主线程

 简单实例

4个线程分别执行loop函数,中间等待nsec秒,nsec分别为4,2,3,5

 1 #!/usr/bin/env python3
2 # coding:utf-8
3 from time import ctime
4 from time import sleep
5 import _thread
6
7 loops = [4, 2, 3, 5]
8
9
10 def loop(nloop, nsec, lock): # 参数依次为:标识,睡眠时间,锁对象
11 print("start loop", nloop, 'at:', ctime())
12 sleep(nsec)
13 print("loop", nloop, "done at:", ctime())
14 lock.release() # 释放锁
15
16
17 def main():
18 print('start at:', ctime())
19 locks = []
20 nloops = range(len(loops))
21
22 for i in nloops:
23 lock = _thread.allocate_lock() # 分配锁对象
24 lock.acquire() # 获取锁对象
25 locks.append(lock)
26
27 for i in nloops:
28 _thread.start_new(loop, (i, loops[i], locks[i]))  //派生新线程
29
30 # 等待所有锁被释放
31 for i in nloops:
32 while(locks[i].locked()):
33 pass
34 print('all DONE at', ctime())
35
36
37 if __name__ == '__main__':
38 main()

执行结果:

start at: Mon Jan 22 16:09:10 2018
start loop 2 at: Mon Jan 22 16:09:10 2018
start loop 1 at: Mon Jan 22 16:09:10 2018
start loop 3 at: Mon Jan 22 16:09:10 2018
start loop 0 at: Mon Jan 22 16:09:10 2018
loop 1 done at: Mon Jan 22 16:09:12 2018
loop 2 done at: Mon Jan 22 16:09:13 2018
loop 0 done at: Mon Jan 22 16:09:14 2018
loop 3 done at: Mon Jan 22 16:09:15 2018
all DONE at Mon Jan 22 16:09:15 2018

分别等待4,2,3,5秒,程序运行总时间5秒。main()函数最后一个循环作用是等待所有子线程退出。

注意事项

_thread对于进程何时退出没有任何控制。当主线程结束时,所有其他线程也都强制结束。不会发出警告或者进行适当的清理。因而python多线程一般使用较为高级的threading模块,它提供了完整的线程控制机制以及信号量机制。

可参考:

python多线程与threading模块

python多线程与_thread模块的更多相关文章

  1. python多线程与threading模块

    python多线程与_thread模块 中介绍了线程的基本概念以及_thread模块的简单示例.然而,_thread模块过于简单,使得我们无法用它来准确地控制线程,本文介绍threading模块,它提 ...

  2. python多线程之_thread

    多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...

  3. Python多线程(threading模块)

    线程(thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. ...

  4. python 多线程,tthread模块比较底层,而threading模块是对thread做了一些包装,multithreading

    Python多线程详解 2016/05/10 · 基础知识 · 1 评论· 多线程 分享到:20 本文作者: 伯乐在线 - 王海波 .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 1.多线程的 ...

  5. python多线程编程-queue模块和生产者-消费者问题

    摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue ...

  6. python 多线程编程之_thread模块

    参考书籍:python核心编程 _thread模块除了可以派生线程外,还提供了基本的同步数据结构,又称为锁对象(lock object,也叫原语锁.简单锁.互斥锁.互斥和二进制信号量). 下面是常用的 ...

  7. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

  8. python的_thread模块来实现多线程(<python核心编程例子>)

    python中_thread模块是一个低级别的多线程模块,它的问题在于主线程运行完毕后,会立马把子线程给结束掉,不加处理地使用_thread模块是不合适的.这里把书中讲述的有关_thread使用的例子 ...

  9. python _thread模块使用

    python关于线程管理的有2个类,_thread(在2.x的版本中叫thread)和threading. # encoding: UTF-8 import thread import time   ...

随机推荐

  1. SQL 练习30

    查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况) SELECT Student.*,CId,score from Student LEFT JOIN SC ON Student.SId = ...

  2. CGO入门和OCR文字识别(非第三方API,有源码,效果好)实战

    这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战 系列文章见: [第四天] GDB调试指南:C++中如何调试生产环境的程序? [第三天] IM敏感词算法原理和实现 [第二天] 现代IM架构研 ...

  3. Vue 如何实现一个底部导航栏组件

    参考网址: https://www.jianshu.com/p/088936b7b1bd/ Vue 如何实现一个底部导航栏组件 可以看到父组件是知道我点击了底部TabBar的哪个item的. 实现 实 ...

  4. spring开发中常见错误集合,逐步添加

    1.关于jstl错误:原因,在jsp页面中使用了jstl标签库,但是却没有导入,可以将相应的jar包放在tomcat的lib目录下,一劳永逸 Java.lang.NoClassDefFoundErro ...

  5. mfc HackerTools拖动文件

    VOID DragAcceptFiles(          HWND hWnd,    BOOL fAccept); 这个函数的调用,表示你要让某个窗体能够接受文件的拖入.第一个参数指定是哪个窗口, ...

  6. Springboot使用MatrixVariable 注解

        根据 URI 规范 RFC 3986 中 URL 的定义,路径片段中可以可以包含键值对.规范中没对对应的术语.一般 "URL 路径参数" 可以被应用,尽管更加独特的 &qu ...

  7. 五分钟搞定Docker安装ElasticSearch

    前言 项目准备上ElasticSearch,为了后期开发不卡壳只能笨鸟先飞,在整个安装过程中遇到以下三个问题. Docker安装非常慢 ElasticSearch-Head连接出现跨域 Elastic ...

  8. 项目版本管理Git使用详细教程

    前言 记得刚开始做项目开发的时候都是一个人完成一个项目,单打独斗的开发,也不知道什么是团队开发,没有这个概念,随着工作后来知道公司里项目都是团队开发,这个时候这么多人怎么开发一个项目呢,难道用u盘拷贝 ...

  9. 前端调用后台接口下载word文档的两种方法

    1传统的ajax虽然能提交到后台,但是返回的数据被解析成json,html,text等字符串,无法响应浏览器下载.就算使用bob模拟下载,数据量大时也不方便 废话不多说:上代码(此处是Layui监听提 ...

  10. servlet+Ajax开发web工程

    前言 因为目前基本已经不会再用到servlet+jsp开发项目了,基本都是使用框架来开发:我们常用的框架都是基于servlet来封装的,该阶段只需要了解一下tomcat如何使用,servlet的生命周 ...