# EasySegmentSupervisedMultiThreadInference

| Support            | ![](assets/images/sample_programs/applies_to/cpp.svg)                                                        |
|--------------------|--------------------------------------------------------------------------------------------------------------|
| Required licenses  | **EasySegment**                                                                                              |
| Recommended images | In the Deep Learning Additional Resources, the images from the folder `EasySegment Supervised/Coffee/Images` |
| Location           | `Deep Learning Inspection/EasySegmentSupervisedMultiThreadInference`                                         |

#### NOTE
- In C#, the sample `EasyClassifyMultiThreadInference` illustrates a multithread inference for **EasyClassify**.
- In Qt, the sample `EasyLocateMultiThreadInference` illustrates a multithread inference for **EasyLocate**.

## Purpose

This sample program demonstrates how to:

- Perform a multithread inference with **EasySegment Supervised** in console mode.
- Implement external and internal multithreading.

## Code highlights

For external multithreading, we use the data structures `ImageQueue` and `ResultQueue` that implement FIFO queues for multithreading applications. It uses mutex and conditional variables to perform the synchronization and the data access control between the threads.

1. Launch one acquisition thread and `NumExternalThreads` processing threads.
   ```c++
   // Create the acquisition thread
   std::thread acquisitionThread(acquireImages, dataset, queue.get());
   // Create the processing threads
   std::vector<std::thread> threads;
   for (int i = 0; i < NumExternalThreads; i++)
   {
     threads.emplace_back(processImage, SegmenterPath, queue.get(), resultQueue.get());
   }
   ```

- The function `acquireImages` loads the images and pushes them into the image queue.
- The function `processImage` applies the tool on the images and pushes the results into the result queue.

1. Set the internal threading for each external thread in the function `processImage`.
   ```c++
   // Set the internal threads
   Easy::SetMaxNumberOfProcessingThreads(NumInternalThreads);
   ```
2. The main thread takes the results from the result queue and displays them in the standard output.
   ```c++
   // Wait and process results
   while (!resultQueue->isComplete())
   {
     ImageResult result = resultQueue->takeResult();
     std::cout << "[" << result.ImageId << "] Processing time: " << result.Time << " | Number of blobs: " << result.Result->GetNumBlobs() << std::endl;
   }
   ```
