由于协程没办法完成(一)中所说的任务模式

接下来就尝试一下使用线程和队列来实现一下这个功能

在实现之前,我们先明确一个问题——python的线程是伪并发的。同一时间只能有一个线程在运行。具体怎样的运作方式由解释器决定

然后回顾一下上一章遇到的问题——return以后,需要另外一个线程去检测之前的操作是否执行成功

因此程序的流程设计应该是这样的:

 # 大致流程步骤如下
 # 1.获取参数(接口被访问时触发)
 request_data = request.form
 # 2.根据参数查询内容
 target = Target.query.filter_by(id=request_data).first()
 # 3.将结果插入队列
 ans_queue.put(target)
 # 4.激活线程
 thread.set()
 # 5.将结果从队列中取出
 ans_queue.get()
 # 6.处理结果
 check()
 # 7.将线程休眠(阻塞)
 thread.event.clear()

这样设计的考虑主要是以下几点:

1.简单

2.入队可以保证消息按时间顺序被处理

3.出队可以保证当队列不为空时,检查线程会执行到队列为空为止。免去不必要的唤醒检查。然后在有消息入队时被重新激活

4.其实我们的设计正常来说不会出现3中的检查情况。基本上队列一旦有消息入队,线程就会启动并清空队列

5.入队可以保证消息的完整和独立性,每次请求得到的数据入队后,队列中都是一列数组。处理逻辑更清晰

6.队列中的数据不出栈是不可见的

7.我就是宁愿用全局队列也不想用全局变量

实际接口代码和线程代码如下:

A.队列和线程代码

 # 消息队列
 lock_queue = Queue()

 def check_kill(event):
     while True:
         # check queue
         if lock_queue.empty() is True:
             event.clear()
         # wait event
         if event.is_set() is not True:
             event.wait()
         # do some work
         sids, serials, minutes, hosts, insts, opasses, ospasses = [], [], [], [], [], [], []

         # get data until queue empty or datas more than 10
         if lock_queue.empty() is not True:
             data = lock_queue.get()
             for i in data:
                 sid, serial, minute, host, inst, opass, ospass = i.split(',')
                 sids.append(sid)
                 serials.append(serial)
                 minutes.append(minute)
                 hosts.append(host)
                 insts.append(inst)
                 opasses.append(opass)
                 ospasses.append(ospass)

         # init the command
         kill_command = 'kill -9'

         # each time we deal less or equal 10 check
         for i in range(len(minutes)):
             current = datetime.datetime.now().minute
             if current >= int(minutes[i]):
                 passtime = current - int(minutes[i])
             else:
                 passtime = current + 60 - int(minutes[i])

             print("passtime is", passtime)
             if (5 - passtime) >= 0:
                 time.sleep((5 - passtime)*60)

             # split piece of list
             sql_sids, sids = sids[0], sids[1:]
             sql_serials, serials = serials[0], serials[1:]
             sql_hosts, hosts = hosts[0], hosts[1:]
             sql_insts, insts = insts[0], insts[1:]
             sql_opass, opasses = opasses[0], opasses[1:]
             sql_ospass, ospasses = ospasses[0], ospasses[1:]

             print("data", sql_hosts, sql_insts, sql_serials, sql_sids)
             # create cursor

             try:
                 conn = sqlite3.connect('data-dev.sqlite')
                 c = conn.cursor()
                 cu = c.execute("select ouser,oport,osport,osuser from tool_target where host='%s' and inst='%s'" % (sql_hosts, sql_insts))

                 result = cu.fetchall()

                 ouser = result[0][0]
                 opass = sql_opass
                 str_conn = (sql_hosts
                             + ':'
                             + str(result[0][1])
                             + '/'
                             + sql_insts)
                 odb = cx_Oracle.connect(ouser, opass, str_conn)
                 cursor = odb.cursor()

                 # select to find if lock exist
                 sql = '''select b.spid, a.sid, a.serial#, a.event from v$session a, v$process b
                         where a.sid = %s and a.serial# = %s ''' % (sql_sids, sql_serials)

                 cursor.execute(sql)
                 answer = cursor.fetchall()
                 print("answer is", answer)
                 kill_command += ' ' + answer[0][0]

                 s = paramiko.SSHClient()
                 s.load_system_host_keys()
                 s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                 s.connect(sql_hosts, result[0][2], result[0][3], sql_ospass)
                 stdin, stdout, stderr = s.exec_command(kill_command)
                 stdout.read()
                 print('------------------------')
                 s.close()
                 cursor.close()
                 odb.close()
                 c.close()
                 conn.close()
             except:
                 pass

 txkill_ready = threading.Event()
 t1 = threading.Thread(target=check_kill, args=(txkill_ready,), name='t1')
 t1.start()
 # txkill_ready.set()

B.接口代码

 @main.route('/txlock/startkillurl', methods=['POST'])
 def start_kill_url():
     if request.method == 'POST':
         cmd = request.form.getlist('list')[0]
         host = request.form.getlist('host')[0]
         inst = request.form.getlist('inst')[0]
         # print(len(cmd))
         # cmd.replace("\n", "")
         # cmd.replace("\t", "")
         # print(len(cmd))

         tooltarget = ToolTarget.query.filter_by(host=host, inst=inst).first()
         ouser = tooltarget.ouser
         opass = ToolTarget.de_rsa(pwd=tooltarget.opass)
         ospass = ToolTarget.de_rsa(pwd=tooltarget.ospass)
         str_conn = (tooltarget.host
                     + ':'
                     + str(tooltarget.oport)
                     + '/'
                     + tooltarget.inst)
         odb = cx_Oracle.connect(ouser, opass, str_conn)
         cursor = odb.cursor()

         # add into queue
         c = re.findall('\d*,\d*', cmd)
         d = [i+','+str(datetime.datetime.now().minute)+','+host+','+inst+','+opass+','+ospass for i in c]
         # data example : ['15,5,17', '16,23,17', '14,5,17', '142,1,17']
         lock_queue.put(d)
         txkill_ready.set()

         try:
             cursor.execute(cmd)
             # pass
         except:
             return "执行失败,关闭弹窗后会自动刷新列表"
     return "执行成功,关闭弹窗后会自动刷新列表"

后台程序处理(二) python threading - queue 模块使用的更多相关文章

  1. python threading queue模块中join setDaemon及task_done的使用方法及示例

    threading:     t.setDaemon(True)  将线程设置成守护线程,主进行结束后,此线程也会被强制结束.如果线程没有设置此值,则主线程执行完毕后还会等待此线程执行.     t. ...

  2. Python之Queue模块

    Queue 1.创建一个“队列”对象 >>> import Queue >>> queue = Queue.Queue(maxsize=100) >>& ...

  3. threading模块和queue模块实现程序并发功能和消息队列

    简介: 通过三个例子熟悉一下python threading模块和queue模块实现程序并发功能和消息队列. 说明:以下实验基于python2.6 基本概念 什么是进程? 拥有独立的地址空间,内存,数 ...

  4. 【Python@Thread】queue模块-生产者消费者问题

    python通过queue模块来提供线程间的通信机制,从而可以让线程分项数据. 个人感觉queue就是管程的概念 一个生产者消费者问题 from random import randint from ...

  5. python --- queue模块使用

    1. 什么是队列? 学过数据结构的人都知道,如果不知道队列,请Google(或百度). 2. 在python中什么是多生产者,多消费模型? 简单来说,就是一边生产(多个生产者),一边消费(多个消费者) ...

  6. python Queue模块

    先看一个很简单的例子 #coding:utf8 import Queue #queue是队列的意思 q=Queue.Queue(maxsize=10) #创建一个queue对象 for i in ra ...

  7. Python之队列queue模块使用 常见问题与用法

    python 中,队列是线程间最常用的交换数据的形式.queue模块是提供队列操作的模块,虽然简单易用,但是不小心的话,还是会出现一些意外. 1. 阻塞模式 import queue q = queu ...

  8. Python学习笔记- Python threading模块

    Python threading模块 直接调用 # !/usr/bin/env python # -*- coding:utf-8 -*- import threading import time d ...

  9. Python多线程(3)——Queue模块

    Queue模块支持先进先出(FIFO)队列,支持多线程的访问,包括一个主要的类型(Queue)和两个异常类(exception classes). Python 2 中的Queue模块在Python ...

随机推荐

  1. iOS(本地通知与远程通知)

    iOS 推送通知有两种:本地推送.远程推送. 本地推送 :  在不需要联网的情况下,由APP发出推送,常用于某一时刻的通知,如闹钟.本地通送有局限性在于当APP处于后台或者退出时就无法发出通知. 远程 ...

  2. linux 下解压rar文件

    今天遇到要在linux 服务器上解压几个rar 文件的问题,rar似乎是win 专属的压缩格式,所以linux 原生工具链中并没有支持rar 解压的工具.经过一系列搜索确定了一个脚linuxrar 的 ...

  3. 百度地图API示例之移动地图

    级别为6 级别为8 级别为12 代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Conten ...

  4. [LeetCode]题解(python):054-Spiral Matrix

    题目来源 https://leetcode.com/problems/spiral-matrix/ Given a matrix of m x n elements (m rows, n column ...

  5. 创建dialog

    创建一个dialog有一下两种方式: 1.Data属性:DOM添加属性data-toggle="dialog"后,单机触发. a链接打开: <a href="jso ...

  6. java学习___File类的创建

    一.使用File创建文件 File file = new File("."+File.separator+"data.dat"); //如果不存在则创建 fil ...

  7. 获取php的配置

    ini_get — 获取一个配置选项的值 返回值 成功是返回配置选项值的字符串,null 的值则返回空字符串.如果配置选项不存在,将会返回 FALSE. <?php /* 我们的 php.ini ...

  8. 自学php笔记

          1,函数名称是不区分大小写的,但是变量名称是区分大小写的, 2,在MySql中sql执行的语句是不分大小写的,但数据库和表名是区分大小写的 3,在sql语句中,字符串要用一组单引号 ' ' ...

  9. 初见IOS的UI之:UI控件的属性frame bounds center 和transform

    这些属性,内部都是结构体:CGRect CGPoint CGFloat 背景知识:所有的控件都是view的子类,屏幕就是一个大的view:每个view都有个viewController,它是view的 ...

  10. bzoj2489

    这种题完全可以暴力找规律,暴力打表各种搞法 这里有一篇比较全面的题解:http://acm.uestc.edu.cn/bbs/read.php?tid=3698&page=1&tore ...