多线程程序

该博客介绍了一个功能,即通过相机实时采集图片,并使用多线程进行处理。采集和处理两个模块通过线程池并行工作,利用循环队列作为数据存储结构,确保高效的数据传递。文章还提到了参考的Python线程池原理及并发编程相关资料。
摘要由CSDN通过智能技术生成

功能描述:相机采集图片,同时对采集的图片进行处理

功能说明:采集和处理两个模块采用线程处理,数据使用循环队列进行存储。

  • 主程序
#encoding: utf-8
'''
该文件用于控制多个相机的采集和算法调用
'''
import time
import uuid, cv2
import numpy as np
import threading
from threading import Thread
from detect_ipl import MASK
from grab_ipl import CAMERAOFFICE, CYCLEQUEUE

class CAMRECOG():
    def __init__(self, ip, channel):
        self.grabObj = CAMERAOFFICE(ip=ip, channel=channel)
        self.maskObj = MASK() #检测是否佩戴口罩的算法
        assert self.grabObj.get_flag_init() , '**cam:{} init failed**'.fromat(ip)
        self.FPS = 2 #单位时间内采集和调用算法的图片数
        self.tm_sleep = 1*1.0/self.FPS  #采集等待时间
        self.queue_buffs = CYCLEQUEUE(20) #保留20帧图片
        self.grab_idx = 0
        self.recog_idx = 0
        pass

    def grab(self): #采集程序
        while True:
            print('grab: {}, threadid: {}'.format(self.grab_idx, threading.current_thread()),  flush=True)
            self.grab_idx += 1
            img = self.grabObj.grab()
            # if isinstance(img, np.ndarray):
            #     cv2.imwrite('rst/grab_{}.jpg'.format(str(uuid.uuid4())), img)
            self.queue_buffs.enqueue(img) #循环队列
            time.sleep(self.tm_sleep)
    def recog(self): #识别程序
        while True:
            print('recog: {}, threadid: {}'.format(self.recog_idx, threading.current_thread()), flush=True)
            self.recog_idx += 1

            if not self.queue_buffs.is_empty():
                img = self.queue_buffs.dequeue()

                # if isinstance(img, np.ndarray):
                #     print('dequeue img: {}'.format(img.shape))
                #     cv2.imwrite('rst/{}.jpg'.format(str(uuid.uuid4())), img)
                rst = self.maskObj.recog(img)
                print(rst, flush=True)
                if rst['returncode'] != 0:
                    print('error: {}'.format(rst))
                    # return
                    continue
                self.maskObj.parseObj.parse(rst['result'])
                if self.maskObj.parseObj.isNoMask():
                    print('!!no mask!!')
            else:
                time.sleep(0.02)  #否则该线程会一直占用GIL导致无法采集

if __name__ == '__main__':
    monitorObj = CAMRECOG(ip='100.18.77.245', channel='101')
    monitorObj2 = CAMRECOG(ip='100.18.10.244', channel='201') #相机初始化

    threads = [] #构建线程池
    t = Thread(target=monitorObj.grab, args=())
    threads.append(t)
    t = Thread(target=monitorObj.recog, args=())
    threads.append(t)
    t = Thread(target=monitorObj2.grab, args=())
    threads.append(t)
    t = Thread(target=monitorObj2.recog, args=())
    threads.append(t)

    threads[0].start() #启动线程
    threads[1].start()
    threads[2].start()
    threads[3].start()
  • 循环队列采用链表对象进行模拟。
class CYCLEQUEUE(object):
    def __init__(self, maxsize):
        self.maxsize = maxsize
        self.reset()

    def reset(self):
        self.queue = [None] * self.maxsize
        self.front = 0
        self.rear = 0


    # 如果队列未满,则在队尾插入元素,时间复杂度O(1)
    def enqueue(self, data):
        if (self.rear + 1) % self.maxsize == self.front:
            print("The queue is full!")
            self.reset() #重置队列内容
        self.queue[self.rear] = data
       # self.queue.insert(self.rear,data)
        self.rear = (self.rear + 1) % self.maxsize

    # 如果队列不为空,则删除队头的元素,时间复杂度O(1)
    def dequeue(self):
        if self.rear == self.front:
            print("The queue is empty!")
        else:
            data = self.queue[self.front]
            self.queue[self.front] = None
            self.front = (self.front + 1) % self.maxsize
            return data

    # 返回当前队列的长度
    def get_length(self):
        return (self.rear - self.front + self.maxsize) % self.maxsize
    def is_empty(self):
        num = self.get_length()
        return num == 0 #不考虑元素覆盖情况
    # 输出队列中的元素
    def get_queue(self):
        for i in range(self.maxsize):
            print(self.queue[i],end=',')
        print(' ')
  • 处理结果

参考文献:

  1. Python 线程池原理及实现

  2. 并发编程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线程 求质数 返回数组中的最大值 bool isPrime(long x) { if (x <= 1) return false; if (x == 2) return true; for (long i = 2; i <= ceil(sqrt((long double)x));i++) if (x%i == 0) return false; return true; } DWORD WINAPI findPrime(void* p) { long result=0; int l = stc(p)->lower, u = stc(p)->uper; int t_id=GetCurrentThreadId(); for (int i = l; i <= u;i++) if (isPrime(i)) { result++; } DWORD dReturn = WaitForSingleObject(mutex_mul_result_h, INFINITE); mul_result += result; ReleaseMutex(mutex_mul_result_h); //EnterCriticalSection(&gCRITICAL_SECTION_Printf); //printf("%d,%d,%d,%d\n", l, u, result,t_id); //fflush(stdout); //LeaveCriticalSection(&gCRITICAL_SECTION_Printf); return 0; } //dispatcher void dispatch() { DWORD Status; timer tm; tm.start(); //srand(time(NULL)); long step = STEP;//ceil(double(TEST/10)); handlenum = 0; for (int i = 1; i <= TEST;) { i += step; handlenum++; } handle_array=new HANDLE[handlenum]; Thread_id = new DWORD[handlenum ]; arg = new FP_ARG[handlenum]; InitializeCriticalSection(&gCRITICAL_SECTION_Printf); mutex_mul_result_h = CreateMutex(NULL, false, mutex_mul_result); handlenum = 0; for (int i = 1; i <= TEST;) { arg[handlenum].lower = i; arg[handlenum].uper = (i + step-1>TEST) ? TEST : i + step-1; handle_array[handlenum]=(HANDLE)CreateThread(NULL, 0, findPrime, &arg[handlenum], 0, &Thread_id[handlenum]); /*EnterCriticalSection(&gCRITICAL_SECTION_Printf); printf("lower:%d uper:%d thread_id:%d\n", arg[handlenum].lower, arg[handlenum].uper,Thread_id[handlenum]); LeaveCriticalSection(&gCRITICAL_SECTION_Printf);*/ i += step; handlenum++; } tm.stop(); Sleep(1000); printf("there are %d threads\n", handlenum); printf("the multithreads use %f msc\n", tm.read()); } //the number of 1-1000000 Primenumber void s_finePrime() { timer tm; long result = 0; tm.start(); for (int i = 1; i <= TEST; i++) if (isPrime(i)) result++; tm.stop(); printf("Single thread result is %d\n", result); printf("Single thread use %f msc\n", tm.read()); } int _tmain(int argc, _TCHAR* argv[]) { dispatch(); WaitForMultipleObjects(handlenum, handle_array, true, INFINITE);//不起作用 printf("the multithreads reslut is %d\n", mul_result); CloseHandle(mutex_mul_result_h); DeleteCriticalSection(&gCRITICAL_SECTION_Printf); s_finePrime(); system("pause"); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值