【使用消息队列在线程之间交换数据(生产者消费者)】

文章目录


  • 此示例演示了消息队列在多个线程之间进行数据传递的基本用法。
  • 这可以通过检测和计数板条箱中的瓶子的应用程序来说明。
  • 主线程首先启动一个单独的获取线程和两个处理线程,然后等待结果。
  • 获取的图像通过消息队列传递给处理线程。处理结果使用另一个消息队列传递回主线程。
  • 一旦输入用完,所有线程都会自动停止。

在这里插入图片描述

dev_update_off ()
* 
* Open windows for reporting the results as they are delivered.
dev_close_window ()
dev_open_window (0, 0, 800, 240, 'black', WindowResults)
set_display_font (WindowResults, 16, 'mono', 'true', 'false')
Message := 'This example demonstrates the basic use of message queues for data'
Message[1] := 'delivery among multiple threads.'
Message[2] := 'The main thread first starts a separate acquisition thread and'
Message[3] := 'two processing threads and then waits for results.'
Message[4] := 'As soon as the input is used up, all threads are stopped automatically.'
disp_message (WindowResults, Message, 'window', 12, 12, 'white', 'false')
disp_continue_message (WindowResults, 'black', 'true')
stop ()
dev_open_window (200, 320, 480, 384, 'black', WindowImage)
* 创建两个队列,一个用于将获取的图像传递给处理线程,另一个用于传递结果。
* Create both queues, one to deliver acquired images to processing threads, the other to deliver results.
create_message_queue (QueueImages)
create_message_queue (QueueResults)
* 启动采集和处理线程。
* Start the acquisition and processing threads.
NumWorkerThreads := 2
for ThreadIndex := 0 to NumWorkerThreads - 1 by 1
    par_start<VProcThreads.at(ThreadIndex)> : processing_thread (QueueImages, QueueResults, ThreadIndex)
endfor
par_start<AcqThread> : acquisition_thread (QueueImages, QueueResults, NumWorkerThreads)
NumStartedThreads := NumWorkerThreads + 1
NumFinishedThreads := 0
* 
* Initialize variables.
dev_update_off ()
NumCrates := 0
NumBottles := 0
NumIncomplete := 0
IncompleteIDs := []
ClutteredIDs := []
StopMessages := []
display_results (WindowResults, NumCrates, NumBottles, NumIncomplete, IncompleteIDs, ClutteredIDs, StopMessages, 0)
* 循环等待来自处理线程的结果。
* Loop waiting for results coming from the processing threads.
while (1)
    * Read next message with results from the queue.
    * 从队列中读取下一条消息及其结果。
    dequeue_message (QueueResults, 'timeout', 'infinite', MessageResult)
    * 
    * Here, the message can be either a real collection of results processing
    * a single input image - or a special message informing about completion
    * of one of the worker threads.
    *在这里,消息可以是处理单个输入图像的实际结果集合,也可以是通知某个工作线程完成的特殊消息。
    get_message_param (MessageResult, 'key_exists', 'thread_finished', ThreadEndInfo)
    if (ThreadEndInfo[0])
        * Worker-thread-finish message, just increment the
        * finished-thread counter.
        * *工作线程完成消息,只需增加完成的线程计数器。
        get_message_tuple (MessageResult, 'thread_finished', ThreadEndMessage)
        StopMessages := [StopMessages,ThreadEndMessage[0]]
        NumFinishedThreads := NumFinishedThreads + 1
    else
        * This message contains real processing results.
        * Retrieve and display the visualization of the results.
        *此消息包含实际处理结果。
        *检索并显示结果的可视化。
        get_message_obj (ImgProcessedCrate, MessageResult, 'processed_crate')
        dev_set_window (WindowImage)
        dev_display (ImgProcessedCrate)
        * Increment the crates/bottles counters and other statistics
        * based on the information delivered in the message
        * from the processing thread.
        *根据处理线程在消息中传递的信息增加板条箱/瓶子计数器和其他统计信息。
        NumCrates := NumCrates + 1
        get_message_tuple (MessageResult, 'num_bottles', NumBottlesInCrate)
        NumBottles := NumBottles + NumBottlesInCrate
        get_message_tuple (MessageResult, 'crate_id', CrateID)
        if (NumBottlesInCrate < 20)
            NumIncomplete := NumIncomplete + 1
            IncompleteIDs := [IncompleteIDs,CrateID]
        endif
        get_message_param (MessageResult, 'key_exists', 'clutter', ClutterPresent)
        if (ClutterPresent[0])
            ClutteredIDs := [ClutteredIDs,CrateID]
        endif
    endif
    * 
    * Update the results display.
    display_results (WindowResults, NumCrates, NumBottles, NumIncomplete, IncompleteIDs, ClutteredIDs, StopMessages, 0)
    * 
    * If all the worker threads finished, stop waiting for the results.
    * 如果所有工作线程都已完成,请停止等待结果。
    if (NumFinishedThreads == NumStartedThreads)
        break
    endif
endwhile
* 
* Final clean up
convert_vector_to_tuple (VProcThreads, ProcThreads)
par_join ([AcqThread,ProcThreads])
* Display final results.
display_results (WindowResults, NumCrates, NumBottles, NumIncomplete, IncompleteIDs, ClutteredIDs, StopMessages, 1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【网络星空】

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值