多线程应用-函数方式(thread)
多线程只能使用一颗CPU,无法发挥多核心的优势。计算密集型用python的多线程效果不明显的,I/O密集型才能看出效果,可以发挥多核优势。
GIL是全局资源锁,所以,如果没有涉及到资源的调用,是不会体现的。另外,如果线程进行的是简单运算,由于运算速度太快,导致线程间请求和释放GIL间隔太短,所以也不能观察到多核CPU跑满的情况。
实例一:多线程ping,默认无法控制线程数量
# -*- coding: UTF-8 -*-
import time,threading,datetime
from time import ctime,sleep
import subprocess,sys
reload(sys) #定义ping函数
def fping(ip):
sc = subprocess.Popen(['ping.exe',ip,'-n',''],shell=True,stdout=subprocess.PIPE)
ls=[]
while sc.poll() == None:
sclines = sc.stdout.readlines()
for l in sclines:
ls.append(l.strip().decode('GBK')+'\n')
#将ls转换为字符串格式,否则在输出的时候每个ping结果会串行
lss=''.join(ls)
print lss #fping('192.168.200.250') stime=datetime.datetime.now() if __name__ =='__main__':
ips=['www.baidu.com','www.163.com','www.sohu.com','www.cctv.com','www.xin.com','apollo.youxinpai.com']
threads=[]
for ip in ips:
#创建并启动进程
t = threading.Thread(target=fping,args=(ip,))
#将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。子线程启动后,父线程也继续执行下去
t.setDaemon(True)
t.start()
threads.append(t)
#等待每个线程结束
for t in threads:
print t.name,t.is_alive(),ctime()
t.join() etime=datetime.datetime.now()
print (etime-stime).seconds,'s'
多线程数量控制(直接控制可以同时启动的线程数量,起来后同时运行,不再控制):
#定义分段函数,变相实现控制线程数量
def lstg(num,lst):
#定义每段的个数num
l = len(lst)
#取分成几组
g = l/num
#判断是否有剩余的数
last = l%num
lstn = []
if num >= l:
lstn.append(lst)
else:
for i in range(g):
i=i+1
n=i*num
m=n-num
lstn.append(lst[m:n]) if last <> 0:
lstn.append(lst[-last:])
return lstn #定义ping函数
def fping(ip):
sc = subprocess.Popen(['ping.exe',ip,'-n',''],shell=True,stdout=subprocess.PIPE)
ls=[]
while sc.poll() == None:
sclines = sc.stdout.readlines()
for l in sclines:
ls.append(l.strip().decode('GBK')+'\n')
#将ls转换为字符串格式,否则在输出的时候每个ping结果会串行
lss=''.join(ls)
print lss #fping('192.168.200.250') stime=datetime.datetime.now() if __name__ =='__main__':
#定义线程数量
tnum = 3
ips=['www.baidu.com','www.163.com','www.sohu.com','www.cctv.com','www.xin.com','apollo.youxinpai.com','www.cmr.com.cn']
for ips in lstg(tnum,ips):
threads=[]
for ip in ips:
#创建并启动进程
t = threading.Thread(target=fping,args=(ip,))
#t.setName('th-'+ ip)
t.setDaemon(True)
t.start()
threads.append(t)
#等待每个线程结束
for t in threads:
#print t.name,t.is_alive(),ctime()
t.join() etime=datetime.datetime.now()
print (etime-stime).seconds,'s'
多线程数量控制(同时启动N个,限制同时可运行的线程数量):
import threading
def query(tnum,mutex,fp):
with tnum: #限制同时运行的线程数量
print fp,threading.currentThread()
time.sleep(2) if __name__ == '__main__':
threads=[]
mutex=threading.Lock()
tnum=threading.Semaphore(5) #定义同时可运行的线程数量为5
files = range(10)
for filepath in files:
t = threading.Thread(target=query,args=(tnum,mutex,filepath))
t.setDaemon(True)
t.start() #同时启动线程数量不限
#print t.name
threads.append(t)
for t in threads:
t.join()
线程未加锁:
# -*- coding: UTF-8 -*-
from time import ctime,sleep
import threading,datetime def fun(mutex,arg1,ts):
global a1
a1=0
a1=arg1+a1
print str(a1)+ ' ' + ctime()
sleep(ts) if __name__ == '__main__':
arg1=2
ts=1 print datetime.datetime.now() mutex = threading.Lock()
threads = []
for arg1 in range(5): t = threading.Thread(target=fun,args=(mutex,arg1,ts)) t.setDaemon(True)
t.start()
threads.append(t)
for t in threads:
t.join()
print a1
a1返回结果为:4
线程加锁:
# -*- coding: UTF-8 -*-
from time import ctime,sleep
import threading,datetime def fun(mutex,arg1,ts):
global a1
a1=0
if mutex.acquire(1): #加锁。锁定方法acquire可以有一个超时时间的可选参数timeout。如果设定了timeout,则在超时后通过返回值可以判断是否得到了锁,从而可以进行一些其他的处理
a1=arg1+a1
print str(a1)+ ' ' + ctime()
sleep(ts)
mutex.release() #释放锁
#print mutex.locked() #判断锁是否还在 if __name__ == '__main__':
arg1=2
ts=1
print datetime.datetime.now() mutex = threading.Lock() #创建锁
threads = []
for arg1 in range(5):
t = threading.Thread(target=fun,args=(mutex,arg1,ts))
t.setDaemon(True)
t.start()
threads.append(t)
for t in threads:
t.join()
print a1
a1返回结果为10
线程锁:http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944771.html
threading.Thread类
这个类表示在单独的控制线程中运行的活动。有两种方法可以指定这种活动,给构造函数传递回调对象,或者在子类中重写run() 方法。其他方法(除了构造函数)都不应在子类中被重写。换句话说,在子类中只有__init__()和run()方法被重写。
一旦线程对象被创建,它的活动需要通过调用线程的start()方法来启动。这方法再调用控制线程中的run方法。
一旦线程被激活,则这线程被认为是'alive'(活动)。当它的run()方法终止时-正常退出或抛出未处理的异常,则活动状态停止。isAlive()方法测试线程是否是活动的。
一个线程能调用别的线程的join()方法。这将阻塞调用线程,直到拥有join()方法的线程的调用终止。
线程有名字。名字能传给构造函数,通过setName()方法设置,用getName()方法获取。
线程能被标识为'daemon thread'(守护线程).这标志的特点是当剩下的全是守护线程时,则Python程序退出。它的初始值继承于创建线程。这标志用setDaemon()方法设置,用isDaemon()获取。
存在'main thread'(主线程),它对应于Python程序的初始控制线程。它不是后台线程。
有可能存在'dummy thread objects'(哑线程对象)被创建。这些线程对应于'alien threads'(外部线程),它们在Python的线程模型之外被启动,像直接从C语言代码中启动。哑线程对象只有有限的功能,它们总是被认为是活动的,守护线程,不能使用join()方法。它们从不能被删除,既然它无法监测到外部线程的中止。
- class Thread(group=None, target=None, name=None, args=(), kwargs={})
-
构造函数能带有关键字参数被调用。这些参数是:
group 应当为 None,为将来实现ThreadGroup类的扩展而保留。
target 是被 run()方法调用的回调对象. 默认应为None, 意味着没有对象被调用。
name 为线程名字。默认,形式为'Thread-N'的唯一的名字被创建,其中N 是比较小的十进制数。
args是目标调用参数的tuple,默认为()。
kwargs是目标调用的参数的关键字dictionary,默认为{}。
如果子线程重写了构造函数,它应保证调用基类的构造函数(Thread.__init__()),在线程中进行其他工作之前。
- start()
- 启动线程活动。
在每个线程对象中最多被调用一次。它安排对象的run() 被调用在一单独的控制线程中。
run()
- 用以表示线程活动的方法。
-
你可能在子类重写这方法。标准的 run()方法调用作为target传递给对象构造函数的回调对象。如果存在参数,一系列关键字参数从args和kwargs参数相应地起作用。
- join([timeout])
- 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
-
当timeout参数未被设置或者不是
None
,它应当是浮点数指明以秒计的操作超时值。因为join()总是返回None
,你必须调用isAlive()来判别超时是否发生。 -
当timeout 参数没有被指定或者是
None
时,操作将被阻塞直至线程中止。 -
线程能被join()许多次。
-
线程不能调用自身的join(),因为这将会引起死锁。
-
在线程启动之前尝试调用join()会发生错误。
- getName()
- 返回线程名。
- setName(name)
- 设置线程名。
-
这名字是只用来进行标识目的的字符串。它没有其他作用。多个线程可以取同一名字。最初的名字通过构造函数设置。
- isAlive()
- 返回线程是否活动的。
-
大致上,线程从 start()调用开始那点至它的run()方法中止返回时,都被认为是活动的。模块函数enumerate()返回活动线程的列表。
- isDaemon()
- 返回线程的守护线程标志。
- setDaemon(daemonic)
- 设置守护线程标志为布尔值daemonic。它必须在start()调用之前被调用。
-
初始值继承至创建线程。
-
当没有活动的非守护线程时,整个Python程序退出
多线程应用-函数方式(thread)的更多相关文章
- 多线程的实现方式01 Thread
/* * 多线程 有三种实现方式 * 其一 Thread * * 写一个类 * * 1.让他继承 Thread * 2.重写thread中的run方法 * 3.创建子类对象就是在 创建线程! * 3. ...
- .net 多线程的使用(Thread)
上篇 net 同步异步 中篇 多线程的使用(Thread) 下篇 net 任务工厂实现异步多线程 Thread多线程概述 上一篇我们介绍了net 的同步与异步,我们异步演示的时候使用的是委托多线程来实 ...
- 多线程应用-类(thread)
在对class thread加锁时,锁无法正常应用,函数方式没问题. 在使用class thread方法时,并发后的查询结果不对,函数方式没问题. # -*- coding: UTF-8 -*- fr ...
- java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁
多线程的实现方式:demo1.demo2 demo1:继承Thread类,重写run()方法 package thread_test; public class ThreadDemo1 extends ...
- 牛客网Java刷题知识点之什么是进程、什么是线程、什么是多线程、多线程的好处和弊端、多线程的创建方式、JVM中的多线程解析、多线程运行图解
不多说,直接上干货! 什么是进程? 正在进行中的程序(直译). 什么是线程? 就是进程中一个负责程序执行的控制单元(执行路径). 见 牛客网Java刷题知识点之进程和线程的区别 什么是多线程? 一个进 ...
- Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别
一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...
- .NET多线程执行函数
前面几篇文章一直在写LINQ,这里为什么会出现多线程?原因是DebugLZQ在写一个LINQ综合Demo的时候遇到了多线程,便停下手来整理一下.关于多线程的文章,园子里很多很多,因此关于多线程理论性的 ...
- “全栈2019”Java多线程第十章:Thread.State线程状态详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- C#多线程编程介绍——使用thread、threadpool、timer
C#多线程编程介绍——使用thread.threadpool.timer 在system.threading 命名空间提供一些使得能进行多线程编程的类和接口,其中线程的创建有以下三种方法:thread ...
随机推荐
- jenkins 踩坑路 之 jenkins ssh 脚本
背景: 由于公司业务调整,整个业务要从阿里云迁移到aws,自然 jenkins 也是要进行迁移的.jenkins 迁移过程中遇到的问题在此记录下,希望能给遇到类似问题的朋友些许帮助.也便于我后期遇到此 ...
- springboot-11-servlet, listener, fitlter的添加
springboot中添加servlet, filter, listener有2种方式: 代码注册servlet 和自动注解注册(在使用druid监控有使用过) 代码注册通过ServletRegist ...
- springboot-7-配置druid数据源监视
关于druid数据源的配置, 上个博客已经说过了,再说一遍吧 , 引入依赖 , 配置properties参数 , 编写servlet和filter提供页面监视 , 测试 1, 引入maven依赖 &l ...
- Linux-(top,free)
top命令 1.命令格式: top [参数] 2.命令功能: 显示当前系统正在执行的进程的相关信息,包括进程ID.内存占用率.CPU占用率等. top命令是Linux下常用的性能分析工具,能够实时显示 ...
- C/C++中的常量到底存在了什么地方
一般来说,基本类型(整型.字符型等)常量会在编译阶段被编译成立即数,占的是代码段的内存.(代码段是只读的,而且不允程序员获取代码段的地址,所以在c++中,尽量不为const分配数据段的内存,但是一旦取 ...
- 用java做操作系统内核:软盘读写
在前两节,我们将一段代码通过软盘加载到了系统内存中,并指示cpu执行加入到内存的代码,事实上,操作系统内核加载也是这么做的.只不过我们加载的代码,最大只能512 byte, 一个操作系统内核,少说也要 ...
- 总结 vb与数据库的连接方法
总结 vb与数据库的连接方法 分类:vb数据库 (4672) (38) 举报 收藏 总结:vb与数据库连接方式,两种分法. 根据是否使用ODBC(驱动程序)来分: 1.有源连接 2.无源连接. ...
- c#基础学习(0709)之vs通过抽象方法实现多态
抽象类不能用来实例化对象 1.抽象类中可以有实例成员,也可以有抽象成员 2.抽象成员不能有任何实现 3.抽象类.抽象成员必须包含在抽象类中 4.抽象类不能用来实例化对象,既然抽象类不能被实例化,那么抽 ...
- ADO调用分页查询存储过程
一.分页存储过程 ----------使用存储过程编写一个分页查询----------------------- set nocount off --关闭SqlServer消息 --set nocou ...
- hdu 3085
Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...