A. 求助python多线程,执行到100多个停止了
python 线程 暂停, 恢复, 退出
我们都知道python中可以是threading模块实现多线程, 但是模块并没有提供暂停, 恢复和停止线程的方法, 一旦线程对象调用start方法后, 只能等到对应的方法函数运行完毕. 也就是说一旦start后, 线程就属于失控状态. 不过, 我们可以自己实现这些. 一般的方法就是循环地判断一个标志位, 一旦标志位到达到预定的值, 就退出循环. 这样就能做到退出线程了. 但暂停和恢复线程就有点难了, 我一直也不清除有什么好的方法, 直到我看到threading中Event对象的wait方法的描述时.
wait([timeout])
Block until the internal flag is true. If the internal flag is true on entry, return immediately. Otherwise, block until another thread calls set() to set the flag to true, or until the optional timeout occurs.
阻塞, 直到内部的标志位为True时. 如果在内部的标志位在进入时为True时, 立即返回. 否则, 阻塞直到其他线程调用set()方法将标准位设为True, 或者到达了可选的timeout时间.
When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof).
This method returns the internal flag on exit, so it will always return True except if a timeout is given and the operation times out.
当给定了timeout参数且不为None, 它应该是一个浮点数,以秒为单位指定操作的超时(或是分数)。
此方法在退出时返回内部标志,因此除非给定了超时且操作超时,否则它将始终返回True。
Changed in version 2.7: Previously, the method always returned None.
2.7版本以前, 这个方法总会返回None.
<br>
利用wait的阻塞机制, 就能够实现暂停和恢复了, 再配合循环判断标识位, 就能实现退出了, 下面是代码示例:
#!/usr/bin/env python
# coding: utf-8
import threading
import time
class Job(threading.Thread):
def __init__(self, *args, **kwargs):
super(Job, self).__init__(*args, **kwargs)
self.__flag = threading.Event() # 用于暂停线程的标识
self.__flag.set() # 设置为True
self.__running = threading.Event() # 用于停止线程的标识
self.__running.set() # 将running设置为True
def run(self):
while self.__running.isSet():
self.__flag.wait() # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回
print time.time()
time.sleep(1)
def pause(self):
self.__flag.clear() # 设置为False, 让线程阻塞
def resume(self):
self.__flag.set() # 设置为True, 让线程停止阻塞
def stop(self):
self.__flag.set() # 将线程从暂停状态恢复, 如何已经暂停的话
self.__running.clear() # 设置为False
下面是测试代码:
a = Job()
a.start()
time.sleep(3)
a.pause()
time.sleep(3)
a.resume()
time.sleep(3)
a.pause()
time.sleep(2)
a.stop()
<br>
测试的结果:
这完成了暂停, 恢复和停止的功能. 但是这里有一个缺点: 无论是暂停还是停止, 都不是瞬时的, 必须等待run函数内部的运行到达标志位判断时才有效. 也就是说操作会滞后一次.
但是这有时也不一定是坏事. 如果run函数中涉及了文件操作或数据库操作等, 完整地运行一次后再退出, 反而能够执行剩余的资源释放操作的代码(例如各种close). 不会出现程序的文件操作符超出上限, 数据库连接未释放等尴尬的情况.
B. Python中级精华-并发之启动和停止线程
为了让代码能够并发执行,向创建线程并在核实的时候销毁它。
由于目的比较单纯,只是讲解基础的线程创建方法,所以可以直接使用threading库中的Thread类来实例化一个线程对象。
例子,用户输入两个数字,并且求其两个数字的四则运算的结果:
除了以上的一些功能以外,在python线程
中没有其他的诸如给线程发信号、设置线程调度属性、执行任何其他高级操作的功能了,如果需要这些功能,就需要手工编写了。
另外,需要注意的是,由于GIL(全局解释器锁)的存在,限制了在python解释器当中只允许运行一个线程。基于这个原因,不停该使用python线程来处理计算密集型的任务,因为在这种任务重我们希望在多个CPU核心上实现并行处理。Python线程更适合于IO处理以及设计阻塞操作的并发执行任务(即等待IO响应或等待数据库取出结果等)。
如何判断线程是否已经启动?
目的:我们加载了一个线程,但是想要知道这个线程什么时候才会开始运行?
方法:
线程的核心特征我认为就是不确定性,因为其什么时候开始运行,什么时候被打断,什么时候恢复执行,这不是程序员能够控制的,而是有系统调度
来完成的。如果遇到像某个线程的运行依托于其他某个线程运行到某个状态时该线程才能开始运行,那么这就是线程同步
问题,同样这个问题非常棘手。要解决这类问题我们要借助threading中的Event对象。
Event其实和条件标记类似,匀速线程
等待某个时间发生。初始状态时事件被设置成0。如果事件没有被设置而线程正在等待该事件,那么线程就会被阻塞,直到事件被设置位置,当有线程设置了这个事件之后,那么就会唤醒正在等待事件的线程,如果线程等待的事件已经设置了,那么线程会继续执行。
一个例子:
如上能够确定的是,主线程会在线程t运行结束时再运行。
C. python threadingd多线程老是出错
把你的代码执行了一下,应该是有两个地方有问题。
1、入参(u'飒飒',)这个改成(u'飒飒'.encode("utf-8"),)
2、t2=threading.Thread(target=movie,args=(u'问问')),这个地方改成
t2=threading.Thread(target=movie,args=(u'问问',))。不然会当成两个参数。
3、第三个不确定你的用途。就是t.setDaemon(True)那个地方。调用setDaemon的时候,子线程会随着主线程一起结束,不氏团迅管子线程是否执行完成。所以有时候会出现执行完了啥输出都没有的情况。如果想让主线程等待歼此子线程,在start后面使用t.join()。这样就会一直都有输出了。
修改完如下:
#coding=utf-8
importthreading
fromtimeimportctime
defmusic(m):
print'在听%s,现在是%s'%(m,ctime())
defmovie(mo):
print'在看%s,现在是%s'%(mo,ctime())
threadList=[]
t1=threading.Thread(target=music,args=(u'飒飒'.encode("utf-8"),))
threadList.append(t1)
t2=threading.Thread(target=movie,args=(u'问问'.encode("utf-8")))
threadList.append(t2)
fortinthreadList:
或茄t.setDaemon(True)
t.start()
#t.join()
D. pyhon多线程无效,不知问题出现在哪里
在python里线程出问题,可能会导致主进程崩溃。 虽然python里的线程是操作系统的真实线程。
那么怎么解决呢?通过我们用进程方式。子进程崩溃后,会完全的释放所有的内存和错误状态。所以进程更安全。 另外通过进程,python可以很好的绕过GIL,这个全局锁问题。
但是进程也是有局限的。不要建立超过CPU总核数的进程,否则效率也不高。
简单的总结一下。
当我们想实现多任务处理时,首先要想到使用multiprocessing, 但是如果觉着进程太笨重,那么就要考虑使用线程。 如果多任务处理中需要处理的太多了,可以考虑多进程,每个进程再采用多线程。如果还处理不要,就要使用轮询模式,比如使用poll event, twisted等方式。如果是GUI方式,则要通过事件机制,或者是消息机制处理,GUI使用单线程。
所以在python里线程不要盲目用, 也不要滥用。 但是线程不安全是事实。如果仅仅是做几个后台任务,则可以考虑使用守护线程做。如果需要做一些危险操作,可能会崩溃的,就用子进程去做。 如果需要高度稳定性,同时并发数又不高的服务。则强烈建议用多进程的multiprocessing模块实现。
在linux或者是unix里,进程的使用代价没有windows高。还是可以接受的。
E. 怎样在python中捕获线程抛出的异常
python的线程中的异常,通常不会给你显示出错的语句。你可以将thread函数,或者是Thread的run里的内容用整个儿的try catch包裹起来。搜索
然后这样
import traceback,sys
try:
threadfun1()
except:
traceback.print_exc(file=sys.stdout)
这样出错的时候就能定位到是哪一行代码了。
因为线程经常出现这种无显示错误位置的情形。后来都形成了习惯,要不把线程放在try catch里。要不就仔细检查线程函数,确保它没有错误,再放出去运行。
另外你还可以将线程函数的功能放在主进程里,单线程运行。这样错误位置就曝露出来了。
仅仅从你这个提示来看是无法定位错误的位置与类型的。
F. python为何多线程报错,单线程没问题
你这个是wmi在多线程中天生的问题,python的wmi的官方文档中有说明,网页贺配链接这个地址中,你仔细看“Use WMI in a thread”这一小节。
但是那个解决方案不是很好用,有些问题上还是会报错,推荐你用wmic,禅纤指多线程中这竖雀个要好用很多。网页链接