添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
玩篮球的铅笔  ·  Spring抛java.lang.Illeg ...·  3 周前    · 
胆小的毛衣  ·  SQL Server 和 MySQL 中的 ...·  1 年前    · 
伤情的豌豆  ·  Use the ...·  1 年前    · 
憨厚的手电筒  ·  如何在VC中使用7z ...·  1 年前    · 

业务需求如下图. 一个业务既要通过webapi实时的接收处理任务, 又需要定时从数据库轮询, 还需要从socket接收数据后,
为了统一方便后面的编程. 和性能提高. 分析了一下, 程序结构设计如下.

分析后结果如下
在这里插入图片描述
数据处理线程是一样的任务, 线程再多也是一个类

业务入口则需要根据具体情况来实现 一个入口就是一个线程, 并且任务内容不同 . 需要是多个类.

本程序通过python实现的, webapi 用到了tornado框架,
定时循环则是简单的while循环

主程序启动代码 start.py

# 所有的数据都从 JobList 中获取的.
jobList =  JobList()
# 启动主干活的线程1
scoring =  DoScoringThread(jobList)
scoring.start()
# 启动主干活的线程2
scoring2 =  DoScoringThread(jobList)
scoring2.start()
# 启动主干活的线程3
scoring3 =  DoScoringThread(jobList)
scoring3.start()
# 从数据库循环取任务的线程
dbing =  FromDBLoopGetJobThread(jobList)
dbing.start()
# 开启webapi服务
WebAPIServer.StartWebAPIServe(jobList)

干活的线程…

import threading # from common.Job.JobList import GetOneJob from common.Job.ScoringBLL import DoScoring import time import traceback #干活的线程 class DoScoringThread(threading.Thread): 自动打分线程 def __init__(self,jobList): threading.Thread.__init__(self) self.jobList = jobList def run(self): while(True): #这一层确保发生错误仍然执行循环 try: self.DoLoop() #发生错误仍然执行循环 except Exception as ex: traceback.print_exc() time.sleep(0.5) # 防止死循环消耗大量资源 def DoLoop(self): #循环去任务池中取任务 while(True): jobkey = self.jobList.GetOneJob() if(jobkey == None): print("线程", threading.currentThread().ident,"未取到任务,休眠...") self.jobList.getThreadEvent().wait() # 没任务等待主线程的通知 else: print("线程", threading.currentThread().ident,"取到任务,开始执行...") DoScoring(jobkey)#

轮询数据库取任务的线程.

import threading  
import time
import traceback
# from common.Job.JobList import AppendJob
class  FromDBLoopGetJobThread(threading.Thread):
        自动从数据库取任务的线程
    def __init__(self,jobList):
        self.jobList = jobList
        threading.Thread.__init__(self)  
    def run(self):
        while(True):     #这一层确保发生错误仍然执行循环
            try:
                self.DoLoop() #发生错误仍然执行循环
            except Exception as ex:
                traceback.print_exc()
                time.sleep(0.5) # 防止死循环消耗大量资源  
    def DoLoop(self):
        #循环去任务池中取任务
        while(True):
            # 从数据库取数据
            jobkey = "任务1111"
            print("从DB新增任务",jobkey)
            self.jobList.AppendJob(jobkey)  #只要调用
            time.sleep(1)

其实入口的调用很简单. 只要调用下面的代码即可.其它的代码自由发挥.

   jobList.AppendJob(jobkey) # 添加的时候, 内部默认会通知工作的线程.

核心代码是 JobList.py 这个类

import threading
class  JobList( ):
        工作任务列表
    def __init__(self):
       self.threadevent =  threading.Event()
       self.lock = threading.RLock()
       self.JobList=[] # 任务列表
    def AppendJob(self,jobkey):
      self.lock.acquire() #加锁
      self.JobList.append(jobkey)
      self.lock.release() # 解锁
      self.threadevent.set() # 通知所有工作的线程, 有活干了, 线程就会从wait后面开始执行调用 GetOneJob 来获取任务
    def getThreadEvent(self):
         获取事件,一般是工作线程用来调用wait用
      return self.threadevent
    def GetOneJob(self):
      获取一个任务
      self.lock.acquire()#加锁
      jobkey = None
      if len(self.JobList) ==  0:
         self.threadevent.clear() # 通知所有工作的线程, 已经没有任务了不要再来取了. 其它线程运行到wait的时候就会挂起, 直到set被调用
      else:
         jobkey = self.JobList.pop(0)
      self.lock.release()# 释放线程锁
      return jobkey  

WebApi的入口代码也一样很简单, 我就不贴了.
在合适的地方调用即可

   jobList.AppendJob(jobkey) # 添加的时候, 内部默认会通知工作的线程.

主要是用的多线程中的 threading.Event() 和 threading.RLock(). 参考了文章
https://blog.csdn.net/qq_34139994/article/details/108416241
https://blog.csdn.net/u012067766/article/details/79734630

Mutex,中文译为互斥体,在.net中也是作为一种线程或进程之间的互斥体存在。即在同一时刻,一个共享资源只允许被某一个线程或进程访问,其他线程或进程需要等待(直至获取互斥锁为止)。 Mutex的使用方式与Monitor很相似,但绝不相同。Monitor支持线程间并发同步,Mutex不但支持线程也支持进程间并发同步。 Mutex有许多需要注意的地方,如果稍不注意,则你会被坑惨! 文章目录一、WebApi调优二、WebApi 应用场景三、WebApi 性能瓶颈定位四、WebApi性能优化手段一-本地缓存五、WebApi 性能优化手段二-分布式缓存六、WebApi 性能优化手段三-Http缓存(响应缓存)七、WebApi 性能优化手段四-数据压缩(响应) 一、WebApi调优 什么是WebApi调优 当浏览器端请求WebApi服务端读写数据需要耗费时间,将耗费的时间缩短,就称之为WebApi调优。 5.下载Java JDKhttps://www.oracle.com/java/technologies/javase-downloads.html 6.打开后页面,点击JDK Downlo... .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 windows xp , windows 7 下默认是2,在服务器操作系统上默认为10. 如果不修改这个并发连接限制,那么客户端同时可以建立的 http 连接数就只有2个或10个。对于一些诸如浏览器或网络蜘蛛的应用,2个或10个并发数量实在太少,大大影响应用的性能。之所以 c#之webapi 不管是因为什么原因,结果是在新出的MVC中,增加了WebAPI,用于提供REST风格的WebService,个人比较喜欢REST风格的WebService,感觉比SOAP要轻量级一些,而且对客户端的要求也更少,更符合网络数据传输的一般模式,客户端完全摆脱了代理和管道来直接和WebService进行交互,具体的区别可以参见Web 服务编程,REST 与 SOAP ASP.NET Web API是一个可扩展的框架,用于构建基于HTTP的服务,这些服务可以被不同平台上的不同应用程序访问,如Web、windows、mobile等。它的工作方式或多或少与ASP.NET MVC web应用程序相同。除了它发送数据作为响应,而不是html视图。它类似于webservice或WCF服务,但例外的是它只支持HTTP协议。 ASP.NET Web API特性 构建RESTful服务的理想平台。 支持asp.net网络请求/响应管道 将HTTP动词映射到方法名。 支持不同格式的响应数据