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 :=2for 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 + 1else
* 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)