Python学习---线程基础学习
线程基础
什么是线程(thread)
线程是CPU调度能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流[换言之,线程就是一堆指令集合],一个进程中可以并发多个线程,每条线程并行执行不同的任务
线程的执行特性
线程只有 3 个基本状态:就绪,执行,阻塞。
线程存在 5 种基本操作来切换线程的状态:派生,阻塞,激活,调度,结束。
什么是进程(Process)
进程,是并发执行的程序在执行过程中操作系统分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位。每一个进程都有一个自己的地址空间,即进程空间或(虚空间)。进程空间的大小 只与处理机的位数有关
进程开辟子进程,子进程完全Copy父进程,比如父进程占用20M,子进程也占用20M,所以开进程比开线程更消耗资源
线程与进程的区别
线程共享创建它的进程的地址空间; 进程有自己的地址空间。
线程可以直接访问其进程的数据段; 进程拥有其父进程的数据段的自己的副本。
线程可以直接与其进程的其他线程通信; 进程必须使用进程间通信与兄弟进程进行通信。
新线程很容易创建; 新线程需要重复父线程。比如父进程占用20M,子进程也占用20M,所以开进程比开线程更消耗资源
线程之间可以相互操作,进程之间不可以
对主线程的更改(取消,优先级更改等)可能会影响进程的其他子线程线程; 父进程的更改不会影响子进程。
问:线程执行快还是执行进程快?[陷阱题]
答: 一样快,跑的内容是一样的
Python可以创建多进程,不严格来说因为有GIL,Python没有多线程,但是可以利用多进程来解决[多进程下不能实现数据共享,可以通过其他解决,协程,堆等方案]实现CPU多核的利用
如果在py里面,任务是IO密集型[不是一直调用CPU执行任务,会有sleep等IO阻塞],多线程,如果计算密集型,可以考虑C开发
线程创建
线程的创建:
1. 直接调用,threading.Thread(target=sayhi,args=(1,)
2. 继承式调用:
直接调用:
import time
import threading
begin=time.time()
def bar(n):
print('bar%s'%n)
time.sleep(3)
def foo(n):
print('foo%s' %n)
time.sleep(2) t1 = threading.Thread(target=bar, args=(1,)) # 创建t1线程对象
t2 = threading.Thread(target=foo, args=(2,)) # 创建t2线程对象
t1.start() # 线程启动,开始抢占CPU资源
t2.start() # 线程启动,开始抢占CPU资源
end=time.time()
t1.join() # 线程阻塞,执行完天t1后执行主线程
t2.join() # 线程阻塞,执行完天t2后执行主线程
end2 = time.time()
print('此时有3个线程,主线程,t1线程, t2线程')
print(end-begin)
print(end2-begin)
继承式调用:
import threading
import time
class MyThread(threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
self.num = num
def run(self): # 定义每个线程要运行的函数
print("running on number:%s" % self.num)
time.sleep(3)
if __name__ == '__main__':
t1 = MyThread(1)
t2 = MyThread(2)
t1.start()
t2.start()
线程常用方法
Thread.join():在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
import threading
from time import ctime,sleep
import time def music(func):
for i in range(2):
print ("Begin listening to %s. %s" %(func,ctime()))
sleep(4)
print("end listening %s"%ctime()) def move(func):
for i in range(2):
print ("Begin watching at the %s! %s" %(func,ctime()))
sleep(5)
print('end watching %s'%ctime()) threads = []
t1 = threading.Thread(target=music,args=('七里香',))
threads.append(t1)
t2 = threading.Thread(target=move,args=('阿甘正传',))
threads.append(t2) if __name__ == '__main__': for t in threads:
t.start() # t1.start(). t2.start()
# t.join() # 串行执行,t1.start()后,进入t1.join()等到t1执行完后在执行t2
# t.join() # Python中默认取最后一个for循环的t2,等价于t2.join()
# t1.join() # 主线程的print()会在第8秒出,最后打印end movies
t.join() # t2.join(),t2执行end后程序结束
print ("all over %s" %ctime())
setDemaon(True):
将线程声明为守护线程,必须在start() 方法调用之前设置, 如果不设置为守护线程程序会被无限挂起。这个方法基本和join是相反的。当我们在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程 就分兵两路,分别运行,那么当主线程完成想退出时,会检验子线程是否完成。如果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是 只要主线程完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以 用setDaemon(True)
import threading
from time import ctime,sleep
import time def music(func):
for i in range(2):
print ("Begin listening to %s. %s" %(func,ctime()))
sleep(4)
print("end listening %s"%ctime()) def move(func):
for i in range(2):
print ("Begin watching at the %s! %s" %(func,ctime()))
sleep(5)
print('end watching %s'%ctime()) threads = []
t1 = threading.Thread(target=music,args=('七里香',))
threads.append(t1)
t2 = threading.Thread(target=move,args=('阿甘正传',))
threads.append(t2) if __name__ == '__main__':
# t2.setDaemon(True) # 执行t1后就结束程序,也就是说不执行 print('end watching %s'%ctime())
for t in threads:
t.setDaemon(True) # 将线程声明为守护线程,必须在start() 方法调用之前设置
t.start() # t1.start(). t2.start()
print ("all over %s" %ctime())
Thread提供线程的方法
thread 模块提供的其他方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。
python 的GIL(Global Interpreter Lock)
解释器原因: 由于Cpython解释的原因,同一时刻只能解释器只能调用一个线程,可以理解Python没有多线程
CPython实现细节:在CPython中,由于全局解释器锁定,只有一个线程可以一次执行Python代码(即使某些面向性能的库可能会克服此限制)。 如果您希望您的应用程序更好地利用多核计算机的计算资源,建议您使用多处理。 但是,如果要同时运行多个I / O密集型任务的话,线程仍然是一个合适的模型。
【更多参考】http://www.cnblogs.com/yuanchenqi/articles/5733873.html
Python学习---线程基础学习的更多相关文章
- vagrant的学习 之 基础学习
vagrant的学习 之 基础学习 本文根据慕课网的视频教程练习,感谢慕课网! 慕课的参考文档地址:https://github.com/apanly/mooc/tree/master/vagrant ...
- Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量
Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程: 1.线程是一堆指令,是操作系统调度 ...
- Spark (Python版) 零基础学习笔记(一)—— 快速入门
由于Scala才刚刚开始学习,还是对python更为熟悉,因此在这记录一下自己的学习过程,主要内容来自于spark的官方帮助文档,这一节的地址为: http://spark.apache.org/do ...
- python 标准库基础学习之开发工具部分1学习
#2个标准库模块放一起学习,这样减少占用地方和空间#标准库之compileall字节编译源文件import compileall,re,sys#作用是查找到python文件,并把它们编译成字节码表示, ...
- java 线程基础学习
今天趁空闲时间看了点线程方面的知识 首先看的是volatile关键字,按照我之前书上看到的一点知识,自己的理解是,volatile关键字会阻止编译优化,因为cpu每次读取数据是并不是从高速缓存中读取, ...
- Python编程:基础学习常见错误整理
# Python学习之错误整理: # 错误一:# TypeError: cannot concatenate 'str' and 'int' objects# 不能连接str和int对象age = 2 ...
- Python学习---Python的框架基础学习
框架基础 框架实质: 所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端 B/S结构的响应: import socket def handle_requ ...
- Spark (Python版) 零基础学习笔记(二)—— Spark Transformations总结及举例
1. map(func) 将func函数作用到数据集的每个元素,生成一个新的分布式的数据集并返回 >>> a = sc.parallelize(('a', 'b', 'c')) &g ...
- python+request 常用基础学习笔记
1.pycharm,避免控制台输出的json内容中文出现乱码. #注:乱码为Unicode格式:\u6d4b\u8bd5.加入如下代码后正确返回中文:测试 get_result = r.json() ...
随机推荐
- ubuntu中ANT的安装和配置
一. 自动安装可以使用sudo apt-get install ant安装,但是这种装法不好.首先安装的ant不是最新的版本,其次还要装一堆其他的附带的东西.所以我才用自己手动ant安装. 二. 手动 ...
- ubuntu系统之难
声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站 ...
- C#中的不可空类型转为可空类型
默认下,C#只有两种类型: 1. 可空类型:(是指可为null) 大部分的对象, 如: Dog dog = null; 2. 不可空类型: 基本值类型,布尔类型等,如: int a = 0 ;//正确 ...
- 九度oj题目1342:寻找最长合法括号序列II
题目1342:寻找最长合法括号序列II(25分) 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:886 解决:361 题目描述: 假如给你一个由’(‘和’)’组成的一个随机的括号序列,当然 ...
- JRebel - 给IDE安装JRebel插件
JRebel对于很多人来说已经并不陌生了,一搜一大把. 用过JRebel后发现,这对于Java开发简直不可缺少. 尽管其价格有点春节国庆期间的各种交通费用——打劫! 即使如此也出现了有"分享 ...
- c#单例(Singleton)模式实现
sealed class Singleton { private Singleton(); public static readonly Singleton Instance=new Singleto ...
- svn在commit后报错:is scheduled for addition, but is missing
今天通过svn 的cr(code review)代码审核后,我欲执行svn ci -m"xxxxxxx(提交注释) ISSUE=3380305",但是没有提交成功,SVN报错啦! ...
- python监控linux内存并写入mongodb
(需要安装psutil 用来获取服务器资源,以及pymongo驱动)#pip install psutil #pip install pymongo #vim memory_monitory.py 文 ...
- rabbitMQ windows 安装 入门(转)
rabbitMQ windows 安装 入门 1.下载,其实erlang不装也是可以的 下载 rabbitMQ :http://www.rabbitmq.com/download.html,安装r ...
- 使用SSH连接LINUX的命令
查看端口号是否被占用 netstat -tunlp|grep 端口号 杀掉 kill-9 pid 后台运行 nohup 应用程序名 & disown -a && exit 屏幕 ...