# Reading, Filtering and Writing in multiple threads

**URL:** https://discourse.itk.org/t/reading-filtering-and-writing-in-multiple-threads/4503
**Category:** Beginner Questions
**Tags:** threads, filter, multiprocessing
**Created:** [October 15, 2021, 11:23am UTC](https://discourse.itk.org/t/reading-filtering-and-writing-in-multiple-threads/4503 "2021-10-15T11:23:41Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Keyn34](https://discourse.itk.org/letter_avatar_proxy/v4/letter/k/9fc29f/32.png) [@Keyn34](https://discourse.itk.org/u/Keyn34)
#### Post date: [October 15, 2021, 11:23am UTC](https://discourse.itk.org/t/reading-filtering-and-writing-in-multiple-threads/4503/1 "2021-10-15T11:23:41Z")

</div>

Hello everyone ( again :D),

Are there any resources or tips on running a function like this

```auto
void multiStaple(std::vector<std::string> inputfiles)
{
        // itk::MultiLabelSTAPLEImageFilter Type
	FilterType::Pointer filter = FilterType::New();
	filter->SetLabelForUndecidedPixels(0);
	filter->SetMaximumNumberOfIterations(1);

	for (size_t i = 0; i < inputfiles.size(); i++)
	{
		ReaderType::Pointer reader = ReaderType::New();
		reader->SetFileName(inputfiles[i]);

		try {
			reader->SetNumberOfThreads(1);
			reader->Update();
		}
		catch (itk::ExceptionObject& error) {
			mu.lock();
			std::cerr << "Error: " << error << std::endl;
			mu.unlock();
		}

		filter->SetInput(i, reader->GetOutput());
	}

	try {
		filter->SetNumberOfThreads(1);
		filter->Update();
	}
	catch (itk::ExceptionObject& error) {
		mu.lock();
		std::cerr << "Error: " << error << std::endl;
		mu.unlock();
	}

	WriterType::Pointer writer = WriterType::New();
	std::string outputFilename = inputfiles[0];
	std::string outputFilepath = std::filesystem::path(outputFilename).parent_path().string() + "\\" + outputFilename + "_filtered.nii";
	
	mu.lock();
	std::cout << "Writing: " << outputFilepath << std::endl;
	mu.unlock();

	writer->SetFileName(outputFilepath);
	writer->SetInput(filter->GetOutput());

	try {
		writer->SetNumberOfThreads(1);
		writer->Update();
	}
	catch (itk::ExceptionObject& error)
	{
		mu.lock();
		std::cerr << "Error: " << error << std::endl;
		mu.unlock();
	}
}

```

in multiple `std::thread`s like

```auto
for (int i = 0; i < maxNumberOfThreads; ++i) {
	threadPool.emplace_back(std::thread(multiStaple, filesets[i]));
}
			
for (std::thread& th : threadPool) {
	th.join();
}

```

Because, as far as I know now, the `itk::MultiLabelSTAPLEImageFilter` does not have an implementation of `ThreadedGenerateData()` (taken from [ImageToImageFilter](https://itk.org/Doxygen/html/classitk_1_1ImageToImageFilter.html)). Therefore it should be theoretically possible to start multiple threads working on different image data, or am I wrong?

When I let it run with a single thread, everything works fine. If I start more than one thread, I get ITK Exceptions during execution. Are there any multithreaded accesses I am not aware of the reader, filter, and writer? In theory, there are no shared resources between the threads, as I only need to run the StapleFilter on multiple different data sets. I could not find any examples of letting filters run in parallel. I would be very grateful if you could show me some, given there are some.

Any suggestions are highly appreciated, as always!

---

<div class="post-metadata">

### Author: ![pip010](https://discourse.itk.org/user_avatar/discourse.itk.org/pip010/32/1363_2.png) [@pip010](https://discourse.itk.org/u/pip010)
#### Post date: [October 21, 2021, 8:30am UTC](https://discourse.itk.org/t/reading-filtering-and-writing-in-multiple-threads/4503/2 "2021-10-21T08:30:44Z")

</div>

Hi Keyn,

Most ITK filters are already parallelized. Meaning, based on the numbers of CPU cores/threads they will try to process data using multiple threads. I am not sure about the IO modules in particular, but this makes less sense ( due to serial nature of IO devices).

So maybe what you truly need is non-blocking (background) processing. There are several ways to achieve it via modern c++, probably the easiest is to use async calls (fire and forget).

Also, no offense, but it is clear you are not experienced in the domain of multi thread programming, maybe you need to start with simpler, isolated examples and build from there.

Best regards.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [October 26, 2021, 3:15pm UTC](https://discourse.itk.org/t/reading-filtering-and-writing-in-multiple-threads/4503/3 "2021-10-26T15:15:05Z")

</div>

> [@Keyn34](#):
>
> ITK Exceptions during execution

Which exceptions are you getting? Your approach to parallelism sounds fine. How is your `threadPool` defined?

---

<div class="post-metadata">

### Author: ![Keyn34](https://discourse.itk.org/letter_avatar_proxy/v4/letter/k/9fc29f/32.png) [@Keyn34](https://discourse.itk.org/u/Keyn34)
#### Post date: [October 30, 2021, 1:56pm UTC](https://discourse.itk.org/t/reading-filtering-and-writing-in-multiple-threads/4503/4 "2021-10-30T13:56:02Z")

</div>

Thank you, @pip010, for your response. I highly appreciate the feedback. I only have experience with the Qt concurrent framework, and the `std::thread`s are indeed new to me. But it appears to me that the fire and forget principle you described is exactly what I tried to replicate - and it turns out it also worked fine after I fixed an issue I had within the `filesets` vector itself.

Thank you as well, @dzenanz, for confirming the idea behind my approach to it. It turns out the faulty point was not the thread handling itself. It was a mistake in the `filesets` vector I provided to the `std::thread`s where I had a sorting issue, meaning the origin of the exception was trying to process the wrong files with different labels and sizes. When I managed to fix the problem, the code ran just as expected!

Again, thank you both so much, and sorry that it took me so long to respond, as I was occupied with a different project.
