`
san_yun
  • 浏览: 2607324 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

实现可中断的线程

 
阅读更多
在《从nginx日志读取URL来做性能测试》(http://san-yun.iteye.com/blog/1679215)这篇文章中我实现了一个python多线程来做性能测试,但存在一个问题,线程不可中断,包括两方面:
1. 用户通过kill命令来中断
2. 程序满足某种条件中断(比如测试量大于1000则退出)

下面是我的实现:
# -*- coding: utf-8 -*-
import re
import urllib2
import json
import threading
import Queue
import os
import time
from time import sleep
from threading import Lock
from signal import signal,SIGTERM,SIGINT,SIGQUIT

class Executor:
	def __init__(self,size):	
		self.queue = Queue.Queue()
		self.tasks = []
		self.running = True

		for i  in range(size):
			t = Task(self.queue)
			t.setDaemon(True)
			t.start()
			self.tasks.append(t)

		self._signal()

	def _signal(self):
		signal(SIGTERM,self._exit)
		signal(SIGINT,self._exit)
		signal(SIGQUIT,self._exit)


	def _exit(self,a=None,b=None):
		print 'clean'
		self.cancel()
	
	def cancel(self):
		for task in self.tasks:
		    while not task.cancel():
		        pass

		self.running = False
		self.onCancel()
				
	def submit(self,call):
		self.queue.put(call)	
	
	def join(self):
		#self.queue.join() queue.join()会阻塞,所以不用
		while self.running and not self.queue.empty():
			sleep(0.1)
			if  self.cancelTrigger():
				self.cancel()

	def setCancelTrigger(self,cancelTrigger):
		self.cancelTrigger = cancelTrigger

	def setOnCancel(self,onCancel):
		self.onCancel = onCancel
		

class Task(threading.Thread):

	def __init__(self,queue):
		threading.Thread.__init__(self)
		self.queue = queue
		self.running = True
		self.canceled = False

	def cancel(self):
		self.canceled=True
		return self.isCanceled()

	def isCanceled(self):
		return self.running==False
	
	def run(self):
		while self.running:
			call = self.queue.get()
			call.run()
			self.queue.task_done()
			if self.canceled:
			    self.running = False


客户端使用:
host = "http://7.s.duitang.com"

thread_count = 10 #并发数
max_count=100     #运行次数

total = 0
fail = 0
avg = 0
lock = Lock()

def cancelTrigger():
    return total>=max_count

def onCancel():
    print 'total %s'%total
    print 'fail %s'%fail
    print 'avg %s'%(avg/total)

if __name__ == "__main__":
    f = open("napi","r")
    executor = Executor(thread_count)
    executor.setCancelTrigger(cancelTrigger)
    executor.setOnCancel(onCancel)
    analysis(f.readlines(),executor)
    executor.join()



在实现的时候比较纠结的点:
1. Task如果不是daemon会导致任务永远不会停止,但是如果Task是daemon线程,main线程结束之后daemon就结束了。所以这时需要实现一个join()来阻塞main线程:
  def join(self):  
        #self.queue.join() queue.join()会阻塞,所以不用  
        while self.running and not self.queue.empty():  
            sleep(0.1)  
            if  self.cancelTrigger():  
                self.cancel()  


2. 线程应该可cancel的,之前是直接修改while isrunning的变量,但这样会导致task其实还没有完成的停止下来。所以对于task我引入两个变量来实现安全的停止。


    def cancel(self):  
        for task in self.tasks:  
            while not task.cancel():  
                pass  
  
        self.running = False  
        self.onCancel()  

    def cancel(self):  
        self.canceled=True  
        return self.isCanceled()  

    def run(self):  
        while self.running:  
            call = self.queue.get()  
            call.run()  
            self.queue.task_done()  
            if self.canceled:  
                self.running = False  


3.对于signal专门写了一片文章记录()
分享到:
评论

相关推荐

    linux的中断线程化实现[借鉴].pdf

    linux的中断线程化实现[借鉴].pdf

    CPU中断——实现多线程机制

    多线程机制,你懂得。。多多多多多下载,谢谢支持,办板报的了,歇息一下

    retrofit实现多线程断点下载,可暂停,开始

    数据库GreenDao+Retrofit实现断点下载多线程,可暂停,继续

    JAVA100例之实例66 实现对线程的控制,中断、挂起、恢复、停止

    JAVA100例之实例66 实现对线程的控制,中断、挂起、恢复、停止

    Java中实现线程的超时中断方法实例

    之前在使用Java实现熔断降级组件的时候,需要实现接口请求的超时中断,通过查找相关资料了解了相关的方法,下面这篇文章主要给大家介绍了关于Java中实现线程的超时中断的相关资料,需要的朋友可以参考下

    jthread:连接和协作可中断线程的C ++类(应变为std

    带有stop_token helper-的加入和协作可中断线程(std :: jthread)的C ++类 参考实施 测试套件 提出用于C ++标准的论文 主要建议) (有关停止回调的初始建议,已与p0660r7合并) 其他次要更新) 主要作者:...

    线程的基本概念、线程类、任务类、线程优先级、sleep()方法、yield()方法、join方法、interrupt()方法

    线程的基本概念、线程类、任务类、线程优先级、sleep()方法(休眠)、yield()方法(礼让)、join方法(合并)、interrupt()方法...在Java中,可以使用Thread类的interrupt()方法实现线程的中断。(run方法执行完毕)

    wince 6.0 外部中断驱动

    ISR的实现在OAL(OEM适配层)中,它只处理最低级的中断响应,通常是获取IRQ和SYSINTR并设置MCU内部的中断控制寄存器。中断处理的主要部分在驱动或者应用的中断处理线程中。中断处理线程与其他普通线程一样,使用同一...

    操作系统多线程与文件系统实现

    使用turbo c提供interrupt关键,在每次时间片中断函数时保存现场的功能实现函数之间的切换;加上TCB管理的结构体,实现线程调度。 物理文件的存储结构 引导块区 FAT区 i节点区 数据区 实现的命令集 命令名称 使用...

    java 多线程设计模式 进程详解

    线程中断 静态方法(有关同步的细节) 总结 第五章 Java线程编程的例子 数据结构和容器 简单的同步例子 一个网络服务器类 AsyncInputStream类 使用TCPServer和AsynclnputStream 总结 第六章 Java线程调度 线程...

    vc实现利用多线程制作模态对话框的进度条

    要制作的进度条,可以显示进度,还可以进行中断操作,还要是模态对话框下面的,也就是在处理一个数据的时候(进度条在更新),不允许切换到程序窗口。

    什么是线程?Java中如何创建和管理线程?(java面试题附答案).txt

    interrupt 方法:中断线程的执行。 synchronized 关键字:用于实现线程的同步,确保多个线程之间的安全访问共享资源。 Lock 接口和 ReentrantLock 类:提供更灵活的线程同步机制。 Executor 框架和线程池:用于管理...

    C#线程锁介绍源码

    lock和Monitor是.NET用一个特殊结构实现的,Monitor对象是完全托管的、完全可移植的,并且在操作系统资源要求方 面可能更为有效,同步速度较快,但不能跨进程同步。lock(Monitor.Enter和Monitor.Exit方法的封装)...

    实现中断方式获取游戏手柄参数

    实现中断方式获取游戏手柄参数 1:创建线程,wait事件并处理。调用EventInputStateStart设置事件处理回调函数;isEvent设置为真。 2:在函数g_pJoystick->EnumObjects( EnumObjectsCallback, ( VOID* )hDlg, DIDFT_...

    线程超时死掉

    解决线程的死掉问题和超时问题特别好使,在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现。 Future接口是Java标准API的一部分,在java.util.concurrent...

    多线程编程的核心思想.doc

    多线程编程的核心思想是指在多线程环境下如何实现线程安全、提高程序效率和可读性。本文将从 Lock 和 Condition 接口开始,讲解多线程编程的核心思想。 一、Lock 接口 Lock 接口是 Java 并发包中的一个核心接口,...

    Java多线程与线程安全实践-基于Http协议的断点续传(源码)

    本毕业设计题目旨在研究和实现一个基于Java多线程与线程安全机制的断点续传下载工具。随着互联网的普及,文件的下载需求日益增加,而大文件的下载往往需要较长的时间,一旦出现网络中断或意外情况,就需要从头开始...

    multithread.js, 在浏览器多线程中轻松实现.zip

    multithread.js, 在浏览器多线程中轻松实现 多线程在浏览器多线程中轻松实现。在不中断用户体验的情况下运行任何业务逻辑。多线程是一个简单的包装器,它消除了处理网络工作者和可以传递对象的麻烦。在不中断用户...

    python多线程,断点续传下载程序

    python多线程,断点续传下载程序,功能比较简单,可以进行二次开发。实现更好用的 功能。

    Java毕业设计-Java多线程与线程安全实践-基于Http协议的断点续传.rar

    Java多线程与线程安全实践-基于Http协议的断点续传.rar 是一个Java毕业设计项目,旨在探讨如何在Java中实现多线程和线程安全,以及如何基于Http协议实现断点续传功能。该项目提供了一个完整的源代码包,可以作为学习...

Global site tag (gtag.js) - Google Analytics