[Back to Blog](/blog) # Teigha Multithreading Low-Level API (Part 3 of 4)

Andrew Markovich February 20, 2018 [\#performance](/blog/tag/performance) [\#Example](/blog/tag/example) [\#getting started](/blog/tag/getting-started)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

This article is part of a series about the low-level API used for multithreading. For the previous articles, see [Part 1](https://www.opendesign.com/blog/2018/january/teigha-multithreading-low-level-api-part-1-4) and [Part 2](https://www.opendesign.com/blog/2018/february/teigha-multithreading-low-level-api-part-2-4).

#### Built-in Teigha Thread ID accessor

Each thread (including the main process thread) on any operating system is represented as a unique operating system atom, so it has its own unique system-level ID. Availability of the Thread ID doesn’t depend on the complexity of the frameworks that initiate threads and processes; this means that, for example, if a thread is started using .NET Framework objects, the thread will also contain a unique system-level ID that can be accessed from underlying native code.

A Thread ID is used by the Threads Counter to communicate with external threads.

From any thread that currently runs Teigha code, you can access the current Thread ID using the Teigha cross-platform odGetCurrentThreadId function:

```
FIRSTDLL_EXPORT unsigned          odGetCurrentThreadId();

```

This ID can be used to identify a thread inside a Teigha Threads Counter object.

#### Example of using the odGetCurrentThreadId() function

We will extend our console output from [Part 2](https://www.opendesign.com/blog/2018/february/teigha-multithreading-low-level-api-part-2-4) about mutex objects. Extend the output string inside the ProcessImageCaller::entryPoint method to output the current Thread ID together with processed scanlines information:

```
pCaller->m_pOutput->addString(OdString().format(OD_T("Thread %u processed scanlines from %u to %u\n"),<br></br>
::odGetCurrentThreadId(), (unsigned)pCaller->m_scanLineFrom, <br></br>
(unsigned)(pCaller->m_scanLineFrom + pCaller->m_nScanLines - 1)));

```

Now the console output of our example application will look like this:

4 files loaded and rendered in 0.413389 seconds  
Thread 8240 processed scanlines from 0 to 255  
Thread 7508 processed scanlines from 256 to 511  
Thread 8776 processed scanlines from 768 to 1023  
Thread 10040 processed scanlines from 512 to 767  
Final raster image processed in 0.543844 seconds

Watch for the final article in this series about atomic operations and using the multithreading low-level API.

## Get started today

**Try ODA software free for 60 days.  
No risk, no credit card required.**

[Try for Free](https://www.opendesign.com/free-trial)
