What is the purpose of the thread entry point method/function? - multithreading

when creating a thread we pass an entry point method/function , why should I have this method , what is the purpose of it?

OS needs to know where a new thread of execution starts. When using a high-level programming language, one does not specify an address of machine instructions in memory to be executed in the context of a new thread, but uses execution units defined in the language like functions or methods. If thread creation worked like fork and execution of a new thread started at the point of fork invocation, then both threads would have the same local variables that usually reside in stack. Even if there is a copy of the stack created for a new thread, both threads will run the same clean-up code when leaving scopes (e.g., in C++ a smart pointer will be freed twice). So when you specify a starting point for a new thread, you are sure it will allocate a stack-frame of its own and function's epilog won't be executed twice.

A thread has to start somewhere. The pthread interface requires you to provide a function of the form
void *start_thread( void *arg );
void * is used because they can refer to anything.
When a thread is created, the function to provide is called as the thread's starting point. Think of it like main() for the thread, but with different argument and return types.

Related

How user threads are really scheduled? How is the OS (kernel) involved in such scheduling?

I’m reading the popular Operating System Concepts book but I can’t get how the user threads are really scheduled. There’s particularly a statement that confuses me :
“User-level threads are managed by a thread library, and the kernel is unaware of them”.
Let’s say I create the process A and 3 threads with the Pthreads library. My assumption is that user threads must be necessarily scheduled by the kernel (OS). Isn’t the OS responsible for allocating CPU? Doesn’t threads have their own registers and stack? So there must be a context switch ( registers switch ) and therefore there also must be some handling by the OS. How can the kernel be unaware of them?
How are user threads exactly scheduled?
In the simplest implementation of user-level threads (a.k.a., "green threads"), there would be a function named yield(). The yield() function is the scheduler. When one thread calls it, it would;
Choose which thread should run next according to the scheduling policy. If it happens to choose the calling thread, it would then simply return. Otherwise, it would...
...Save whatever registers any called function in the high-level language is obliged to save in the saved context area for the calling thread. This would include, at a minimum, the stack pointer. It probably also would include a frame pointer, and maybe a few general purpose registers.
...Restore the registers from the saved context area for the chosen thread. This would include the stack pointer, and since we're changing the stack pointer in mid-stream, so to speak, we'll have to be very careful about where the scheduler's own variables are kept. It won't really work for it to have "local" variables in the usual sense. There's a good chance that at least part of this "context switch" code will have to be written in assembly language,
Finally, all it has to do is a normal function return, and it will be returning from a yield() call in the chosen thread instead of the original thread.
The function to create a new thread would;
Allocate a block of memory for the thread's stack,
Construct an artificial stack frame in the new stack that looks like the following function just called yield() from the line marked "// 1";
void root_function(void (*thread_function)(void* args)) {
yield(); // 1
thread_function(args);
mark_my_own_saved_context_as_dead();
yield(); // 2
}
When the thread_function() returns, the thread will call the mark_my_own_saved_context_as_dead() function to notify the scheduler algorithm that the thread is dead. When the thread called yield() for the last time ("// 2"), then the scheduler algorithm would free up its stack, and clean up whatever else needs to be cleaned up before selecting some other thread to run.
In a typical implementation of green threads, there will be many other places where one thread implicitly yields to another. Any blocking I/O call, for example, or a sleep(), or any call to acquire a mutex or a semaphore.

Does every thread have its main function?

Does every thread have its own main function?
I know that its have its own stack, but what about main function (not necessarily a function which called main).
For example, when creating a thread, we pass a function as an argument for the new thread to run it.
I tried to search about this topic, but couldn't find answers.
Quote from this article:
In a multi-threaded process, all of the process’ threads share the same memory and open files. Within the shared memory, each thread gets its own stack. Each thread has its own instruction pointer and registers. Since the memory is shared, it is important to note that there is no memory protection among the threads in a process.
Therefore, the «main» function could be called the function with which the execution of the thread begins, i.e. the address of the first instruction of which is initially loaded into the instruction pointer. It is worth noting that the first code that is executed in a thread can be a routine in the standard library that initializes and then calls a user-supplied function, which in this case can be called the «main».
But this is not a common term, it is usually called simply, a thread function.
However, there is a concept, the main thread. This is the first thread that is executed when the program (process) starts.

Will Mutex protection failed for register promotion?

In an article about c++11 memory order, author show an example reasoning "threads lib will not work in c++03"
for (...){
...
if (mt) pthread_mutex_lock(...);
x=...x...
if (mt) pthread_mutex_unlock(...);
}
//should not have data-race
//but if "clever" compiler use a technique called
//"register promotion" , code become like this:
r = x;
for (...){
...
if (mt) {
x=r; pthread_mutex_lock(...); r=x;
}
r=...r...
if (mt) {
x=r; pthread_mutex_unlock(...); r=x;
}
x=r;
There are 3 question:
1.Is this promotion only break the mutex protection in c++03?What about c language?
2.c++03 thread libs become unwork?
3.Any other promotion may caused same problem?
If it's wrong example, then thread libs work, what about the 《Threads Cannot be Implemented as a Library》by Hans Boehm.
POSIX functions pthread_mutex_lock and pthread_mutex_unlock are memory barriers, the compiler and/or CPU cannot reorder loads and stores around them. Otherwise the mutexes would be useless. That article is probably inaccurate.
See POSIX 4.12 Memory Synchronization:
Applications shall ensure that access to any memory location by more than one thread of control (threads or processes) is restricted such that no thread of control can read or modify a memory location while another thread of control may be modifying it. Such access is restricted using functions that synchronize thread execution and also synchronize memory with respect to other threads. The following functions synchronize memory with respect to other threads: [see the list on the website]
For single thread code, the state in the abstract machine is not directly observable: objects that aren't volatile are not guaranteed to have any particular state when you pause the only thread with a signal and observe it via ptrace or the equivalent. The only requirement is that the program execution has the same observable behavior as a behavior of one possible execution of the abstract machine.
The observables are the interactions with external world; basically, input/output on streams and actions on volatile objects.
A compiler for mono-thread code can generate code that perform operations on global variables or other object that happen to be shared between threads, as long as the single thread semantic is respected. This is obviously the case if a global variable to changed in such a way that it gets back its original value.
For example, a compiler might emit code that increment then decrement a variable, at least in some rare cases; the goal would be to emit simple code, at the cost of the occasional few unneeded operations.
Such changes to shared variables that don't exist in the abstract machine would obviously break multithreaded code that concurrently performs a real operation; such code does not have any race condition on the accesses of the shared variable, that are properly serialized, but the generated code introduced a race that breaks the program.

Why are slots being called from the main thread?

I have a Qt application that has two threads: the main thread that handles the GUI and a second thread that manages network connections. Here is the thread code:
void thread::run()
{
QTcpServer server;
server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));
//...
}
When I put a breakpoint at the start of OnConnect() and debug the application, it announces that OnConnect() is being called from the main thread!
How can I have OnConnect() run in the same thread as the QTcpServer?
To give a more thorough answer, look a little deeper into how signal-slot connections and thread contexts interact. Basically, for more connections (auto-connect), the slot will be directly called if both the emitter and the receiver are in the same thread context, otherwise it will be a queued connection, and the slot will be run in the thread context of the object that contains the slot. In this case, it must be queued, which implies that your thread is part of the main application's thread context, not its own. This is reinforced by the documentation Qt provides for an overview of its threading, where it states that the QThread instance is "owned" by the thread context that created it, not the thread context that it represents. This means you have three main choices:
You can use moveToThread() to move the thread into its own context. Note that this may cause problems when deleting the thread unless you move it back to the context where it will be destroyed, and this can only be done in the source-thread context, so it would have to be done before the run function exited.
You can treat the QThread instance as a handle to the thread, not as being part of the thread itself. If you need things done in the context of the new thread, create a different object to handle those, and instantiate them in the context of the new thread (inside the run function). This is what I would recommend.
Force a direct connection. This means you would need to ensure the code running in the slot is thread-safe, ignoring Qt's built-in methods of making those functions thread-safe. This is what you have done.
It seems like the problem was that I wasn't passing Qt::DirectConnection as the last parameter of connect().
After adding that, it worked.

Has anyone seen a programming language that handles threads like this?

Most of the multithreaded work I have done has been in C/C++, Python, or Delphi (Object Pascal). All on Windows. I'll use Delphi for my discussion here. Delphi has a nice class called TThread which abstracts the thread creation process. The class provides an Execute method which is the created thread's thread function. You override that method and typically create a loop within it that exits when the thread is terminated. You do the thread's work inside the loop.
One of the recurring tasks that crops up is keeping track (carefully) of which code gets executed in the thread's context and which code gets executed by external threads in an external context, with synchronization objects guarding data shared by the threads. All basic thread programming stuff. One of the recurring annoyances is creating functions to allow external threads to submit or retrieve data, and moving data from public thread-safe memory objects to those private to the thread and back the other way.
I was wondering if anyone has ever seen a programming language that makes this simpler? Here's what I would love as a programming thread idiom. Let's take a Delphi TThread sub-class created for this discussion. Suppose I could mark class methods with one of three keywords like Private, PublicExecuteInAnyContext, or PublicExecuteInPrivateContext. Here's how they would work.
Private: Private methods would only execute in the thread's context. The compiler would automatically add code that would raise an exception if a code path led to that method being executed in a context outside of the host thread. (E.g. - "Error, attempt to execute method private to thread $AEB from thread $EE0").
PublicExecuteInAnyContext: methods marked as such could be called by the thread that owns the method and any external thread. Any data objects referenced in these methods would automatically be guarded with synchronization objects, with the option to override the default choice and supply your own. (Mutex or semaphore instead of Critical Section, etc.)
PublicExecuteInPrivateContext: Methods marked with this keyword would execute in the thread's context, but are callable by any thread. This option would allow for two strategies for dealing with calls to such methods by external threads:
1) Mode 1 - Block calling thread: the calling thread would block until the method returned. In other words the compiler would automatically write code to make the calling thread would block. Any parameters passed by the calling thread would be copied into variables private to the host thread. The method would not execute until the host thread received control. When the host thread exited the method the calling thread would be released and would have any results returned by the method copied into it's own private variable space.
2) Mode 2 - Do not block the calling thread: this would allow for the additional argument of a callback function. Any parameters passed to the method by an external thread would be copied into the thread's private variable space. The compiler would again hold the execution of the method until the host thread received control, but would let the calling thread continue without blocking. When the host thread completed execution of the method, if a callback function was specified, it would call that function ** but in the context of the original thread that called the method, not in the host thread context **.
A language that would provide this kind of automatic thread handling would, at least to me, be a lot more fun to do multithreading with then the way I have to do it now. Has anybody seen a programming language, or a module/hack for one of the mainstream languages, that provides this kind of multi-threading model?
I don't think it matches your description exactly, but Erlang provides one of the easiest concurrency models I've seen. It uses a share-nothing approach, which may or may not sound appealing to you, but I found it really interesting. It's also really easy to create distributed systems with it, if you ever have the need. Check out "Getting Started with Erlang", it's a great tutorial that covers almost all parts of the language.
Wanted to mention. LabVIEW really makes starting with multi threading a breeze. I just found some article on the Internet which actually explains this in a better way:
If you have programmed in a
traditional, textual language before,
the data-flow paradigm of Labview can
be somewhat hard to embrace. The
data-flow paradigm stipulates that it
does not matter where on the 2D
surface of the block diagram a
particular component is placed in
relation to other components, but what
other components it is wired to. A
particular component-node does not
execute until all its inputs are
available; it executes, however, as
soon as all its inputs are available,
regardless of what else might be
executing at the same time, that is -
in parallel with potentially many
other things.
You need extensive experience with
multi-threading programming in a
traditional language, however, to
truly appreciate how easy it is to
achieve multi-threading with LabVIEW
and how naturally the parallelism
arises - whether intentionally, or
not. While LabVIEW does not magically
dissolve all the challenges related to
parallel processing, it certainly
makes it considerably simpler to get
started with it. In fact, in contrast
with the traditionally sequential
textual programming languages, its is
the sequential execution that comes at
a price in LabVIEW - parallelism is
almost free.
Taken from http://saberrobotics.org/?id=34

Resources