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

实现可中断的线程

 
阅读更多
在《从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专门写了一片文章记录()
分享到:
评论

相关推荐

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

    ### CPU中断——实现多线程机制 #### 一、引言 在计算机系统中,多线程机制是一种常见的技术手段,用于提高程序的执行效率和响应能力。它允许在一个进程中同时运行多个线程,每个线程都可以独立地执行任务。为了...

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

    在Linux操作系统中,中断线程化是一种将中断处理与用户空间任务解耦合的技术,它允许中断处理程序在后台执行,从而改善系统响应时间...对于软件开发者来说,理解和掌握中断线程化有助于优化设备驱动和系统服务的实现。

    java中断线程的正确姿势完整示例.rar

    在Java编程中,中断线程是一项重要的任务,特别是在多线程环境下,我们可能需要停止某个线程的执行,以优化程序资源的使用或响应特定的系统需求。本示例将详细探讨Java中断线程的正确方法,以确保线程安全且高效地...

    创建线程类轻松实现线程管理

    - **中断线程**:通过调用`interrupt()`方法可以请求线程停止执行,但实际停止需要线程内部配合检查`isInterrupted()`或捕获`InterruptedException`。 - **死锁**:当两个或更多线程相互等待对方释放资源而造成的一...

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

    1. 使用 Thread.interrupt() 方法设置线程的中断标志,但是这并不能真正中断线程,而是通知线程可以被中断。 2. 使用 ScheduledThreadPoolExecutor 来延迟执行任务,任务中执行线程的 interrupt() 方法。 使用 ...

    理解多线程,写一个多线程应用程序,要求能在用户级实现线程的调度,如启动、挂起、恢复、停止,的C thread、java thread实现。

    Java中,`join`方法有类似功能,而`interrupt`方法可以用来中断线程,通常配合`isInterrupted`或`interrupted`检查中断状态。 在实际应用中,线程调度还需要考虑线程同步和互斥问题,以防止数据竞争和死锁。C语言中...

    Java基本功之中断线程的理解[参考].pdf

    以下是对Java中断线程的详细解释: 1. **线程终止条件**: - 当`run`方法执行完毕。 - `return`语句执行,提前结束`run`方法。 - 出现未捕获的异常,导致`run`方法终止。 2. **`stop`方法的弃用**: Java早期...

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

    在Android开发中,为了提供更好的用户体验,我们常常需要实现文件的多线程断点下载功能。这不仅可以提高下载速度,还能允许用户在任何时候暂停或继续下载。本篇将重点讲解如何利用Retrofit库和GreenDao数据库来实现...

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

    现在,推荐使用`wait()`和`notify()`或`notifyAll()`来实现线程的挂起和恢复。当一个线程调用`wait()`时,它会释放持有的锁并进入等待状态,直到其他线程调用同一对象的`notify()`或`notifyAll()`唤醒它。 3. **...

    Android实现多线程下载

    实现多线程下载时,为了应对网络不稳定或设备中断等情况,需要支持断点续传。这需要保存每个线程下载的起始位置和已下载长度,当下载暂停或重启时,可以从上次的位置继续下载。 6. **文件分块与合并**: 每个线程...

    Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈

    在Linux系统中,栈可以分为进程栈、线程栈、内核栈以及中断栈。 首先,我们需要了解栈(Stack)的基本概念。栈是一种后进先出(LIFO, Last In First Out)的数据结构,它允许数据被存储和检索,但只允许在一段称为...

    可并行递归算法的递归多线程实现

    为了实现并行性,`try-catch`块被用来捕获可能的中断异常,确保线程能够正确地与其他线程协同工作。 #### 扩展至一般递归算法 对于非尾递归的子线程,父线程在启动递归子线程后,可以通过调用子线程的`join()`方法...

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

    7. **结束线程**:当工作线程完成或被中断时,不要忘记清理资源,如释放同步对象,并调用`AfxEndThread()`来结束线程。 8. **测试与调试**:最后,编译并运行项目,测试进度条是否正常显示、更新以及响应用户的中断...

    Java实现的多线程下载工具

    Java实现的多线程下载工具是一种利用Java编程语言来提高文件下载效率的技术。在传统的单线程下载方式中,文件的下载过程由一个线程执行,可能会受到网络波动、服务器响应速度等因素的影响,导致下载速度慢且不稳定。...

    stm32单片机多线程实例

    5. **中断服务程序与线程交互**:理解中断服务程序如何在中断发生时快速响应,并与线程安全地交换数据。 6. **线程调度与优先级**:了解RT-Thread的调度策略,如静态优先级调度、动态优先级调度等,以及如何调整...

    pb多线程实现的例程

    - 线程控制:包括join()(等待线程执行完毕)、interrupt()(中断线程)和yield()(让出CPU执行权)等方法。 4. **线程同步与通信**: - 竞态条件:当多个线程访问和修改同一数据时,可能会出现不一致的结果。...

    c/c++线程断点续传实现

    在C/C++编程中,实现线程断点续传是一项技术挑战,特别是在处理大文件下载时,这种功能显得尤为重要。断点续传允许程序在中断后从上次停止的地方继续下载,提高了用户体验并节省了网络资源。Cocos2dx是一个基于C++的...

    winform实现多线程下载

    本文将深入探讨如何在WinForm应用程序中实现多线程下载。 首先,了解多线程的基本概念至关重要。线程是程序执行的最小单位,一个进程中可以有多个线程同时运行。在下载场景中,多线程可以让我们同时从服务器获取多...

    DOS下多线程的实现

    1. **中断和DOS扩展器(DOS Extenders)**:DOS本身不支持保护模式,而多线程通常需要这种模式来实现内存管理和上下文切换。DOS扩展器如DPMI(DOS Protected Mode Interface)或LX(Linux/ix for DOS)提供了一种...

    Java线程超时监控

    // 超时后中断线程 System.out.println("Task timed out."); } if (thread.isAlive()) { // 检查线程是否还在运行 // 如果线程仍在运行,可能需要采取其他措施 } ``` 在这种情况下,`join`方法会让调用线程等待...

Global site tag (gtag.js) - Google Analytics