Let's say there're two threads(pthread) in a C++ program:
the main thread
the child thread
What the program does is simple:
Bind the two threads to two different cores.
Set the priorities of the two threads to some very high values (-99 for the child thread and -98 for the main thread).
The child thread is doing some heavy task that is using 100% of the CPU.
The main thread is trying the call printf() after the child thread is created.
The problem is that once the child thread is created, it freezes stdout and nothing gets printed on the console anymore. However, when the program exits, all the messages suddenly shown up in the console. Below is a .cpp file demonstrating this effect:
main.cpp:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
bool EXIT = false;
void signal_handler(int signal){
EXIT = true;
}
void *child_thread(void *x_args){
printf("Setting child thread CPU affinity (Core #1)...\n");
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(1, &cpuset);
if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)){
perror("Cannot set child thread CPU affinity");
printf("Exit\n");
exit(1);
}
printf("Locking memory of child thread...\n");
mlockall(MCL_CURRENT | MCL_FUTURE);
printf("Setting child thread priority (-99)...\n");
struct sched_param sched_param;
sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
if (sched_setscheduler(0, SCHED_FIFO, &sched_param)){
perror("Cannot set child thread priority");
printf("Exit\n");
exit(1);
}
printf("Entering while loop inside child thread...\n");
while(!EXIT){}
return NULL;
}
int main(){
signal(SIGINT, signal_handler);
pthread_t thread;
printf("Setting main thread CPU affinity (Core #0)...\n");
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset);
if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)){
perror("Cannot set main thread CPU affinity");
printf("Exit.\n");
exit(1);
}
printf("Locking memory of main thread...\n");
mlockall(MCL_CURRENT | MCL_FUTURE);
printf("Setting main thread priority (-98)...\n");
struct sched_param sched_param;
sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO)-2;
if (sched_setscheduler(0, SCHED_FIFO, &sched_param)){
perror("Cannot set main thread priority");
printf("Exit.\n");
exit(1);
}
printf("Creating child thread...\n");
if (pthread_create(&thread, NULL, child_thread, NULL)){
perror("Cannot create child thread");
printf("Exit.\n");
exit(1);
}
printf("Entering while loop in main thread...\n");
while(!EXIT){
sleep(1);
printf("I can't see this until I press Ctrl+C!\n");
}
pthread_join(thread, NULL);
printf("Exit.\n");
return 0;
}
You can compile it with:
g++ main.cpp -pthread -o main
Then run it with:
sudo ./main
Then you should see stdout freezes after outputing the following:
Setting main thread CPU affinity (Core #0)...
Locking memory of main thread...
Setting main thread priority (-98)...
Creating child thread...
Entering while loop in main thread...
Setting child thread CPU affinity (Core #1)...
Even after an hour you just won't see anymore outputs. But when Ctrl+C is pressed. You will see all the messages coming out:
I can't see this until I press Ctrl+C!
I can't see this until I press Ctrl+C!
I can't see this until I press Ctrl+C!
I can't see this until I press Ctrl+C!
I can't see this until I press Ctrl+C!
I can't see this until I press Ctrl+C!
I can't see this until I press Ctrl+C!
I can't see this until I press Ctrl+C!
The main thread is actually running in the background because if you comment out the two lines inside the while loop (the sleep and printf), you can see that it is also using 100% of CPU. But ht
What am I missing here?
I won't claim to be an expert but you appear to have a single resource, stdout, and two threads attempting to use it. I believe printf is thread safe, but not reentrent.
My fist instinct would be to use some kind of thread safe locking around the access to printf and stdout to ensure only one thread is calling it at a time.
Related
I want to know if its possible to interrupt main thread and ask it to execute some callback. The main thread should continue with what it was doing after completing the callback.
For instance, we have 2 threads t1 and m1 (main thread). t1 will interrupt m1 (main thread) and ask it to call a function with some parameters. The m1 (main thread) will stop doing what it was doing before and will start executing the function. The after finishing the function, it will get back to what it was doing earlier.
I want to replicate what hardware interrupt does. I have one thread that reads data from a file. Then it should ask main thread to call a function. Main thread will be doing something. It should stop doing it and start executing the function. After completing it, main thread should continue with what it was doing
A clean way I think would be to have a queue of operations that t1 adds to, that t2 checks at points in its processing loop where it is safe to start doing something else.
On POSIX systems, you can use signals. For example, the following starts a second thread and, while the main thread is doing other work, this second thread sends it a SIGUSR1 signal. The main thread handles it and resumes operation.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
void* other_thread(void* main_thread) {
printf("other_thread: %x\n", pthread_self());
usleep(250*1000);
printf("sending SIGUSR1 to main thread...\n");
pthread_kill((pthread_t) main_thread, SIGUSR1);
return NULL;
}
void my_handler(int signal) {
printf("my_handler: %x\n", pthread_self());
sleep(2);
printf("back to main\n");
}
int main(int argc, char**argv) {
signal(SIGUSR1, my_handler);
pthread_t thread1;
pthread_create(&thread1, NULL, other_thread, pthread_self());
printf("main: %x\n", pthread_self());
int x = 0;
while (1) {
// sleep(1), or do some work, or:
x++;
if (x % 10000000 == 0) printf("boo\n");
}
}
I wish to create a thread in a child process before the respective child process changes it's image using exec system call. However, seemingly, the pthread_create call is being overlooked.
pthread_t thread;
pthread_attr_t attribute;
pthread_attr_init(&attribute);
pthread_attr_setdetachstate(&attribute, PTHREAD_CREATE_DETACHED);
pid_t cid = fork();
if(cid == 0) //CHILD Process
{
switch(x->option)
{
case 1: pthread_create(&thread, &attribute, compressShow, NULL);
execl("/home/aamir/Lab/ass3/compression", "compression", source, destination, NULL);
cout<<"Execution failed."<<endl; break; //This segment will execute if exec fails.
}
else //PARENT Process
{
wait(0); //Prevents termination of original main until forked exec completes execution
pthread_cancel(thread);
}
The thread is basically just a progress display that is intended to output '.' (dots) in concurrence with the forked child.
If I remove the exec call the thread does execute. I've searched on google and read somewhere that you cannot use pthread_create between a fork and exec, something to do with async safe functions. Can you please help?
The exec bit zapps everything including threads and just starts a new process. That includes memory etc.
The program might (and usually) does not get to the bit to fire up the thread.
How do I wait for a thread to die in Windows? This is what I want my code to look like:
main thread:
creating thread: thread1
waiting for thread1 to die
//rest of the code
I am using Win32 API.
It's easy: the WaitForSingleObject can block current thread given the other thread's handle.
void Thread1Proc()
{
HANDLE hThread2 = CreateThread(...);
WaitForSingleObject(hThread2, INFINITE);
// by now thread #2 is over
}
I have a process that starts several threads which do some stuff, listen to some ports, etc.
After it starts all threads, the main thread currently goes into an infinite loop:
It's something like:
int main()
{
//start threads
while (true)
{
sleep(1000);
}
}
The extra sleep assures the main thread doesn't eat the processor.
Is this approach ok? Is there an industry standard on how a process is kept alivet? Thanks.
EDIT: Some clarifications:
the threads are listeners, so a join or WaitForSingleObject isn't an option. Usually I could use join here, but the threads are started by a third client library and I don't have any control over them.
doing some processing in the main thread doesn't make sense from a design point of view.
. Taken partially from the Linux Daemon Writing HOWTO, I assume you want something like this:
int main() {
pid_t pid;
/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
// now start threads & do the work
for( thread *t : threads ) {
join( t );
}
return 0;
}
This way the main process will exit, child process will spawn threads which will do the work. In the end the child process will wait for those threads to finish before exiting itself.
I'd suggest you to have your main thread waiting for the termination of the others:
int main( ) {
// start threads
for( thread *t : threads ) {
join( t );
}
// finalize everything or restart the thread
return 0;
}
If you're using POSIX threads, the pthread_join function will do this.
I don't believe that there is an industry standard.
What you have is a perfectly acceptable way of running the main thread. However you may want to include a way to break out of the loop.
Other methods include:
Waiting for all the worker threads to complete using a join command.
Waiting on an event in the the main thread which can be signalled to exit the loop.
Using the main thread to do some of the processing currently done by a worker thread.
Periodically checking a boolean flag to decide whether to exit or not.
At the end of the day, it depends on your specific requirements.
I'm migrating a multi threaded application from HP-UX to Solaris and so far, everything is OK except for one thing! The application has a thread that is handling the signals and, when some of them are received, it runs some cleaning (logging, kill child processes and so on).
I've reduced the code as much as it was possible to make a somehow simple example showing the problem:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <synch.h>
#include <iostream>
#include <unistd.h>
using namespace std;
pthread_t m_signalHandlerThread;
sigset_t m_signalSet;
void signalHandler()
{
while ( true )
{
cout << "SigWait..." << endl;
sigwait( &m_signalSet, &sig );
cout << "Signal!! : " << sig << endl;
break;
}
cout << "OUT" << endl;
}
void* signalHandlerThreadFunction( void* arg )
{
signalHandler();
return (void*)0;
}
int main()
{
sigemptyset( &m_signalSet );
sigaddset( &m_signalSet, SIGQUIT ); //kill -QUIT
sigaddset( &m_signalSet, SIGTERM ); //kill
sigaddset( &m_signalSet, SIGINT ); //ctrl-C
sigaddset( &m_signalSet, SIGHUP ); //reload config
if ( pthread_create( &m_signalHandlerThread, NULL, signalHandlerThreadFunction, NULL ) )
{
cout << "cannot create signal handler thread, system shut down.\n" << endl;
}
int iTimeout = 0;
while (1)
{
if (iTimeout >= 10)
break;
sleep(1);
iTimeout++;
cout << "Waiting... " << iTimeout << endl;
}
cout << "END" << endl;
exit (0);
}
Using compile command lines:
Solaris:
CC -m64 -g temp.cpp -D_POSIX_PTHREAD_SEMANTICS -lpthread
HP-UX:
/opt/aCC/bin/aCC +p +DA2.0W -AA -g -z -lpthread -mt -I/usr/include temp.cpp
Running both applications, the behaviour (pressing CTRL+C while in the 10 seconds loop):
HP-UX:
./a.out
SigWait...
Waiting... 1
Waiting... 2
Signal!! : 2 <---- CTRL + C
OUT
Waiting... 3
Waiting... 4 <---- CTRL + C again to terminate
Solaris:
./a.out
SigWait...
Waiting... 1
Waiting... 2 <---- CTRL + C
^C
Any help will be more then welcome since I'm already tearing my hair (not much left) :)!
Thanks!
It's unspecified which of your 2 threads will handle SIGINT. If you need only one of your threads to handle the signal, you need to block that signal in all the other threads you have.
You should block signals to other threads by using pthread_sigmask. that page also contains an example for a program with a signal handling thread.
About the only way how to handle signals well in multithreaded application is to do the following:
Block all signals in main() early, before any other threads are spawned, using pthread_sigmask().
Spawn a signals handling thread. Use sigwait() or sigwaitinfo() to handle the signals in a simple loop.
This way no threads except the one dedicated for signal handling will get the signals. Also, since the signal delivery is synchronous this way, you can use any inter-thread communication facilities you have, unlike inside classic signal handlers.
This is rather unorthodox way to handle signals. If you want to marry the signals and threads, better choice would be to have the usual signal handlers from where the signal is serialized internally to another thread which is responsible for the actual handling of the event.
That is also a better option, as it is undefined which thread in an MT application receives the signal. Any threads which doesn't have the signal blocked might receive it. If you have 2 threads (and you have two threads in the example) then any of the threads might get the SIGINT.
You might want to check sigprocmask() as a way to tell OS that SIGINT should be blocked in a thread. That should be done for every thread, IIRC even the one calling sigwait().
Edit1. Actually I'm wrong about the "should be done for every thread" bit above. A new thread inherits its signal mask from the current thread. I have realized that that can't be true because that would have introduced the race condition: signal arrives at the time when new thread created but hasn't yet set its signal mask. In other words, it is sufficient to set the signal mask in the main thread.