The C and C++ standards support the concept of signal. However, the C11 standard says that the function signal() cannot be called in multi-threaded environments, or the behavior is undefined. But I think the signal mechanism is by nature for multi-threaded environments.
A quote from the C11 standard 7.14.1.1.7
"Use of this function in a multi-threaded program results in undefined behavior. The
implementation shall behave as if no library function calls the signal function."
Any explanations about this?
The following code is self-evident.
#include <thread>
#include <csignal>
using namespace std;
void SignalHandler(int)
{
// Which thread context here?
}
void f()
{
//
// Running in another thread context.
//
raise(SIGINT); // Is this call safe?
}
int main()
{
//
// Register the signal handler in main thread context.
//
signal(SIGINT, SignalHandler);
thread(f).join();
}
But I think the signal mechanism is by nature for multi-threaded environments.
I think this sentence is the central misunderstanding. signal() is a method for inter-process communication, not for inter-thread. Threads share common memory and can therefore communicate via mutexes and control structures. Processes don't have common memory and must make-do with some explicit communication structures like signal() or the filesystem.
I think you're confusing signaling, which is process specific, with communication between threads. If it is sharing information between threads that you're after, you will probably find what you want in the new C++11 thread support library. Of course, it depends on what you really want to do.
From what I can tell of your code, you want a thread to "signal" an event in some way and you want to be able to run some code when that event is signalled. Given that, I'd take a closer look at the Futures section in the thread support library.
The C11 standard's statement that "Use of this function in a multi-threaded program results in undefined behavior," refers specifically to the function signal(). So the question is if the use of signal() is done "in a multi-threaded program."
The term 'multi-threaded program' isn't defined in the C standard as far as I can tell, but I would take it to mean a program in which multiple threads of execution have been created and have not completed. That would mean that at the time signal() is called in your example program the program is not multi-threaded and therefore the program's behavior is not undefined under this requirement.
(However C++11 requires that "All signal handlers shall have C linkage," [18.10 Other runtime support [support.runtime] p9]. Since your example program uses a handler with C++ linkage the behavior is undefined.)
As others have pointed out signals aren't intended for communication between threads. For example the C and C++ standards don't even specify what thread they run on. The standard library instead provides other tools for inter-thread communcation, such as mutexes, atomics, etc.
I think you just misintrepret the term undefined behavior, which is unfortunately much overloaded to mean "bad things will happen". Here the term really just means what it says: the C standard doesn't make any assumption about what it means to use signal in a multi-threaded context.
In general the signal/raise interface in the C standard is not very useful by itself, but only a placeholder for platform/OS specific things that are defined on top of it.
So for an interaction between signal and threats doesn't give you a contract. Or stated otherwise, the interaction of signal and threads is left to the platform
implementation.
Related
I searched a lot but none answered my question, I read that it's not safe to use cout in signal handlers like this:
void ctrlZHandler(int sig_num) {
//SIGTSTP-18
std::cout << "smash: got ctrl-Z" << std::endl;
SmallShell::route_signal(sig_num);
}
will it solve the problem if I move the printing inside route_signal?
Is there a lists of safe-to-call functions in C++11?
What if the only solution to use write, can you show me short example, and let's say route_signal have 100 printings should I replace all with write()? that sounds exhausting with the need to allocate memory and free...
The reason why using std::cout inside signal handlers isn't recommented is because signals might interrupt your running code whenever and std::cout::operator << is not reentrant.
This means if you are executing std::cout::operator << when a signal is raised that also uses it within it's execution, the result is undefined.
So, no. Moving it into route_signal would not solve this and you should replace every call of std::cout within!
One workaround would be to set a flag that this signal was received and create a output outside the signal handler after it returned.
Signal handlers need to run quickly and be reentrant, which is why they shouldn’t call output stream functions like cout <<, either directly or indirectly.
If you are doing this temporarily under controlled conditions for testing, it might be okay, but make sure the signal you are handling is not triggered again until the handler has finished and be aware that stream functions can be slow, which might mess up your tests as well.
will it solve the problem if I move the printing inside route_signal?
No.
Is there a lists of safe-to-call functions in C++11?
For practical purposes, the only safe thing you can do is set a volatile sig_atomic_t or lock-free atomic flag inside a signal handler. (N3690 intro.execution §1.9 ¶6)
I'm no C nor C++ language lawyer, but I believe anything permitted in a conforming C application is allowed in a C++11 signal handler. However, that set is very, very limited: abort, quick_exit, _Exit, and signal. (ISO/IEC 9899:2011 §7.14.1.1 ¶5).
What if the only solution to use write, can you show me short example, and let's say route_signal have 100 printings should I replace all with write()? that sounds exhausting with the need to allocate memory and free...
A better solution is to redesign your program to use sigwait or to check that a flag safely set inside the signal handler.
If you insist on using write, and if you trust that it is safe to call inside a signal handler in your C++ implementation — which it probably is but, again, is not guaranteed by C++ itself — then you simply have a coding problem. You'll need to figure out formatting yourself, bearing in mind that even on POSIX-conforming systems malloc and free are not async-signal-safe. It can certainly be done.
Trying to understand :
C.2.9 Clause 19: diagnostics library [diff.cpp03.diagnostics]
19.4
Change: Thread-local error numbers
Rationale: Support for new thread facilities.
Effect on original feature: Valid but implementation-specific C++ 2003 code that relies on errno being the same across threads may change behavior in this International Standard.
I understand <error.h> content is in header <cerrno> but we have to define errno as a macro. Can anyone explain what we can do so that errno would act the same way as it was in C++03 during multi-threading?
You don’t need to change anything.
The change in the standard is purely because C++03 had no notion of threads, and the abstract machine model used by the standard to describe the semantics of standard C++ code needed to be updated for C++11 to support threads.
But the observable behaviour of errno in conforming C++ code stayed roughly the same, with the sole exception that errno is now defined thread-locally, and if your code assumes that the value of errno is the same across threads it will break.
C++11 us the first official standard that has a notion of multi-threading. This implies that if you use multiple threads in C++03 or C++98 you are using undefined behavior.
The whole idea about this change is about the following code:
functionThatSetsErrNo();
if (errno == something)
...
If you run this code and the execution results in functionThatSetsErrNo of thread 1, followed by functionThatSetsErrNo of thread 2, followed by the if-statements these if-statements do the right thing in C++11 and gave you a race condition in C++03 possibly combined with the errno of the second execution.
So what did change? If you after calling functionThatSetsErrNo started a thread, that thread no longer can read the errno value. Or similarly, if you have synchronization between threads and one calls the function and the other reads errno.
I hope this indicates that this change ain't too much to worry about as this delayed requesting of errno is something that is barely done and relying on transfer over threads is even done less.
If you do end up with this situation, you need to put a global std::atomic in your program and after execution assign errno into it while reading it from another thread. Although, I actually would recommend getting rid of such strange behavior.
How can I stop/cancel an asynchronous task created with std::async and policy std::launch::async? In other words, I have started a task running on another thread, using future object. Is there a way to cancel or stop the running task?
In short no.
Longer explanation: There is no safe way to cancel any threads in standard C++. This would require thread cancellation. This feature has been discussed many times during the C++11 standardisation and the general consensus is that there is no safe way to do so. To my knowledge there were three main considered ways to do thread cancellation in C++.
Abort the thread. This would be rather like an emergency stop. Unfortunately it would result in no stack unwinding or destructors called. The thread could have been in any state so possibly holding mutexes, having heap allocated data which would be leaked, etc. This was clearly never going to be considered for long since it would make the entire program undefined. If you want to do this yourself however just use native_handle to do it. It will however be non-portable.
Compulsory cancellation/interruption points. When a thread cancel is requested it internally sets some variable so that next time any of a predefined set of interruption points is called (such as sleep, wait, etc) it will throw some exception. This would cause the stack to unwind and cleanup can be done. Unfortunately this type of system makes it very difficult make any code exception safe since most multithreaded code can then suddenly throw. This is the model that boost.thread uses. It uses disable_interruption to work around some of the problems but it is still exceedingly difficult to get right for anything but the simplest of cases. Boost.thread uses this model but it has always been considered risky and understandably it was not accepted into the standard along with the rest.
Voluntary cancellation/interruption points. ultimately this boils down to checking some condition yourself when you want to and if appropriate exiting the thread yourself in a controlled fashion. I vaguely recall some talk about adding some library features to help with this but it was never agreed upon.
I would just use a variation of 3. If you are using lambdas for instance it would be quite easy to reference an atomic "cancel" variable which you can check from time to time.
In C++11 (I think) there is no standard way to cancel a thread. If you get std::thread::native_handle(), you can do something with it but that's not portable.
maybe you can do like this way by checking some condition:
class Timer{
public:
Timer():timer_destory(false){}
~Timer(){
timer_destory=true;
for(auto result:async_result){
result.get();
}
}
int register_event(){
async_result.push_back(
std::async(std::launch::async,[](std::atomic<bool>& timer_destory){
while(!timer_destory){
//do something
}
},std::ref(timer_destory))
);
}
private:
std::vector<std::future<int>> async_result;
std::atomic<bool> timer_destory;
}
Does the main function we define in C or C++ run in a process or thread.
If it runs in a thread, which process is responsible for spawning it
main() is the entry point for your program. C++ (current C++ anyway) doesn't know what a process or thread is. The word 'process' is not even in the index of the standard. What happens before and after main() is mostly implementation defined. So, the answer to your question is also implementation defined.
In general though most operating systems have the concept of process and thread and they have similar meanings (though in Linux, for example, a thread is actually a "light weight process"). You can generally assume that your program will be started in a new process and that main() will then be called by the original thread after the implementation defined initialization.
Since there's plenty of room for the implementation and/or you to start up a whole bunch of threads before main is called though you will probably generally want to consider main() to have been called during the execution of a thread. The best way to think about it though is probably in terms of the standard unless you really have to think about the implementation. The standard doesn't currently know what a process or thread is. C++0x will change that in some way but I'm not sure at this point what the new concepts will be or how they will relate to OS specific constructs.
My answer is specifically addressed at the C++ language part of the question. C is a different language and I haven't used it in a good 10 years so I forget how the globals initialization is specified.
It's a process that you spawn when you execute your program. The main function is called at the beginning of the program. It is all a part of the same program (i.e. one process).
When you ask your OS to start a new process, it initializes data structures for a process and for a single thread inside that process. The initial instruction pointer in that thread context is the process entry point, which is a function provided by your C runtime library. That library-provided entry point converts the environment table and command-line arguments into the format demanded by the C standard, and then calls your main function.
Your whole program is a single process unless it starts fork()ing things, and by default the process has one thread that does everything; main() starts on that thread
At some point I remember reading that threads can't be safely created until the first line of main(), because compilers insert special code to make threading work that runs during static initialization time. So if you have a global object that creates a thread on construction, your program may crash. But now I can't find the original article, and I'm curious how strong a restriction this is -- is it strictly true by the standard? Is it true on most compilers? Will it remain true in C++0x? Is it possible for a standards conforming compiler to make static initialization itself multithreaded? (e.g. detecting that two global objects don't touch one another, and initializing them on separate threads to accelerate program startup)
Edit: To clarify, I'm trying to at least get a feel for whether implementations really differ significantly in this respect, or if it's something that's pseudo-standard. For example, technically the standard allows for shuffling the layout of members that belong to different access specifiers (public/protected/etc.). But no compiler I know of actually does this.
What you're talking about isn't strictly in the language but in the C Run Time Library (CRT).
For a start, if you create a thread using a native call such as CreateThread() on windows then you can do it anywhere you'd like because it goes straight to the OS with no intervention of the CRT.
The other option you usually have is to use _beginthread() which is part of the CRT. There are some advantages to using _beginthread() such as having a thread-safe errno. Read more about this here. If you're going to create threads using _beginthread() there could be some issues because the initializations needed for _beginthread() might not be in place.
This touches on a more general issue of what exactly happens before main() and in what order. Basically you have the program's entry point function which takes care of everything that needs to happen before main() with Visual Studio you can actually look at this piece of code which is in the CRT and find out for yourself what exactly's going on there. The easyest way to get to that code is to stop a breakpoint in your code and look at the stack frames before main()
The underlying problem is a Windows restriction on what you can and cannot do in DllMain. In particular, you're not supposed to create threads in DllMain. Static initialization often happens from DllMain. Then it follows logically that you can't create threads during static initialization.
As far as I can tell from reading the C++0x/1x draft, starting a thread prior to main() is fine, but still subject to the normal pitfalls of static initialization. A conforming implementation will have to make sure the code to intialize threading executes before any static or thread constructors do.