1

I would like to implement an application in C/C++ that runs on Windows and Linux-based OS, the application will be multithreaded so after some research I found there are separate library methods for Windows and Linux respectively.

HANDLE CreateThread( // Windows
  LPSECURITY_ATTRIBUTES   lpThreadAttributes,
  SIZE_T                  dwStackSize,
  LPTHREAD_START_ROUTINE  lpStartAddress,
  __drv_aliasesMem LPVOID lpParameter,
  DWORD                   dwCreationFlags,
  LPDWORD                 lpThreadId
);
// Linux
int pthread_create( pthread_t* thread,
                    const pthread_attr_t* attr,
                    void* (*start_routine)(void* ),
                    void* arg );

According to Microsoft's Documentation, CreateThread seems to use a virtual addressing for the thread's execution, which in my understanding this thread is a "User-level" Thread.

While pthread_create on the other hand, from an answer to a similar question here,

"For example, every single process in a Linux system is a "kernel thread". And every user-created pthread is ALSO implemented as a new kernel thread."

So I suppose pthread_create does create a kernel-based thread.

Comparing User-level threads and Kernel-level threads, I have came across an article / tutorial on this topic in Tutorial Point:

enter image description here

(This image comes from that page.)

Which means User-level threads from the same process will most likely share a Kernel-level thread. (This isn't multi-threading but parallel execution?)

As I want my application to have the same behavior (performance or execution wise) across both platforms, there is 2 question that I want to ask:

  1. Whether the thread created from CreateThread maps 1:1 to a kernel thread? (Which means the application can utilize multi-core processing.)
  2. If the answer to Question (1) is false, are there any methods that equates or emulates the behavior of pthread_create in Windows platform? (There is a PsCreateSystemThread for Windows but I am not sure whether the thread it creates has a similar if not higher privilege of operation compares to the one from pthread_create)
Alphaharrius
  • 210
  • 1
  • 9
  • That's pretty easy -- you can use pthreads in Linux and there are ports for windows through MinGW, there are no ports of windows threading for Linux. Your other alternative is just to use conditional code blocks if compiling on windows or Linux, e.g. `#if defined (_WIN32) || defined (_WIN64) /* add your windows thread setup here */ #else /* add your Linux pthread setup here */ #endif` (but that would take some common thread API to implement functionality of each.) – David C. Rankin Feb 02 '21 at 08:54
  • "CreateThread seems to use a virtual addressing for the thread's execution, which in my understanding this thread is a "User-level" Thread." Hm, I don't follow this part. One has nothing to do with the other. – John Kugelman Feb 02 '21 at 08:57
  • @JohnKugelman So does it mean the thread created by "CreateThread" does have the same effect execution wise as a thread created by "pthread_create"? Or I have overlooked the problem. – Alphaharrius Feb 02 '21 at 09:03
  • Thread support is built into C++' standard library. You're going to have to make up your mind whether your application is going to be written in C or C++. – IInspectable Feb 02 '21 at 10:02

1 Answers1

2

You're very much confusing two things here: user-level threads and kernel-level threads are one thing. What those mean is that with user-level threads the kernel cannot schedule them independently because it does not know about them; and with kernel-level threads the kernel can schedule each thread independently i.e. decide to run them on separate cores simultaneously or wake up independently of each other.

AFAIK, the pthread API does not dictate either one model to be used. But the current Linux implementation, the NPTL i.e. Native POSIX Thread Library uses kernel-level threads (or has one-to-one mapping of kernel threads to user threads).

Whether the threads share the same virtual address space is completely distinct thing - if they share the same address space then each thread can see memory modifications committed by other threads. If they do not share the address space then they won't see the modifications made into memory made by the other threads of execution. In Linux parlance a separate virtual address space is called a process.

  • Isn't shared address space vs different address space the very definition of thread vs process? A thread which doesn't share address space with other threads seems mildly useful. – Lundin Feb 02 '21 at 09:42
  • @Lundin no. A process has 1 or more threads... or possibly even 0. The confusion arises from the fact that in original Unix each process had exactly one thread. – Antti Haapala -- Слава Україні Feb 02 '21 at 09:46
  • @AnttiHaapala Refering to your statement: ```What those mean is that with user-level threads the kernel cannot schedule them independently because it does not know about them; and with kernel-level threads the kernel can schedule each thread independently i.e. decide to run them on separate cores simultaneously or wake up independently of each other.``` Does this mean that I need to direct the user-level threads to run on multiple cores? As the Kernel is unable to do that. – Alphaharrius Feb 03 '21 at 08:32
  • well in the worst case the user-level threads would always compete on one core... – Antti Haapala -- Слава Україні Feb 03 '21 at 09:02
  • @AnttiHaapala If I want to prevent all these threads to compete for execution, are there a suggested / standard way of doing so? Thanks you very much! – Alphaharrius Feb 03 '21 at 10:01