Context switch doesn't accure to main thread in UNIX - multithreading

I have a simpale program that should create two threads with a function hundler that will run infnite and a main thread.
Whenever I try to do pthread_join or pthread_exit to the main thread (in order to demonstrate that the children threads are still working after pthread_exit from main) there is never seems to be a context switch back to the main thread in order to print the message saying he is ending his job "Goodbye" (even the goodbye message before the thread creation is not printed, so I am not exactly sure what is the problem).Only the function handlers of the threads are printing what they should. I set sleep of 4 secs in the other threads in order to see this message before they start, there should have been a context switch to the only thread available that isn't sleeping (main)..
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread(void *vargp) {
sleep(4);
while(1)
printf("First Thread No' %ld\n",pthread_self());
}
void *thread2(void *vargp) {
sleep(4);
while(1)
printf("Second Thread No' %ld\n",pthread_self());
}
int main() {
int j,i = 42;
pthread_t tid, tid2;
printf("Good bye1");
pthread_create(&tid, NULL, thread, (void*)&i);
pthread_create(&tid2, NULL, thread2, (void*)&i);
printf("Good bye");
pthread_exit(NULL);
//pthread_join(tid, (void**)&i);
//pthread_join(tid2, (void**)&j);
}

Related

Why is Linux signal always handled by main thread?

I use pthread_create to get 2 threads and register the signal handler in both created thread.
In main thread, the signal handler is not set.
#include <signal.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
void sig_hand(int no) //signal handler
{
printf("handler executing...\n");
printf("%d\n", pthread_self());
pthread_exit(NULL);
}
void* thread1(void *arg1) //thread1
{
signal(SIGINT, sig_hand);
printf("%d\n", pthread_self());
}
void * thread2(void * arg2) //thread2
{
signal(SIGINT , sig_hand);
printf("%d\n", pthread_self());
}
int main()
{
pthread_t t1;
pthread_t t2;
sigset_t newmask;
sigaddset(&newmask, SIGINT);
// set sigproc, SIGINT can be received;
// sigproc not set, SIGINT can't be received
if(sigprocmask(SIG_BLOCK, &newmask, NULL) < 0){
perror("sigprocmask error");
}
printf("main thread %d\n", pthread_self());
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
while(1);
}
If I don't set sigprocmask in main thread, SIGINT can be received, but it is handled by the main thread while main thread doesn't register handler function.
main thread -1335200000
-1343535360
-1351928064
^Cpthread -1335200000 handler executing...
However if sigprocmask is set in the main thread, SIGINT can't be received while two child threads have registerd handler function.
main thread 2061661952
2053326592
2044933888
^C^C
This is very confusing.

Why does exception of one thread stop the whole process

I was told if one thread got some error, the whole process would be stopped. I used the c++11 code as below to do a simple test:
#include <iostream>
#include <thread>
#include <chrono>
void func1()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout<<"exception!!!"<<std::endl;
throw(std::string("exception"));
}
void func2()
{
while (true)
{
std::cout<<"hello world"<<std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}
I compiled (g++ -std=c++11 -lpthread test.cpp) and executed it.
5 seconds later, I did get an error: Aborted (core dumped)
In my opinion, each thread has it own stack. In this example, if the stack of t1 dies, why can't the t2 continue?
As a thread only has its stack as private, all other things (heap, bss, data, text, env) are shared between threads. One thread crash will lead to the whole process crash, so t1 affected t2 in your program.

C++11 thread detach not working

I understand that when a new thread is spawned it must be joined or detached else terminate shall be called, i have the below piece of code which work fine if i join them, but crashes if i call detach instead, I am not able to understand what's going on under the hood.
#include "iostream"
#include "thread"
#include "vector"
#include "algorithm"
#include "iterator"
#include "string"
#include "memory"
using namespace std;
void func() {
cout << " func ";
}
int main(int argc , char** argv)
{
std::vector< std::thread> m_vec;
for(int i = 0; i < 100 ; i++){
m_vec.push_back( std::thread(func));
m_vec[i].detach();
}
return 0;
}
Just detaching a thread doesn't give it permission to outlive the main thread. Once the main thread exits, that's the ballgame; the heap is destroyed, things like cout are cleaned up. Any remaining threads stand a distinct chance of crashing if they do anything before the process as a whole terminates.
If you detach a thread, be prepared to provide your own mechanism for ensuring it does not outlive the main thread.

Mutex unlock failure when trying to acquire a QSemaphore

I have an application with 2 QThreads which behave like it in the pseudocode below (the semaphores are of type QSemaphore):
Thread1 {
print("about to wait on semaphore 1");
sem1.acquire(1);
print("finished waiting on semaphore 1");
sem2.release(1);
}
Thread2 {
print("signaling semaphore 1");
sem1.release(1);
print("about to wait on semaphore 2");
sem2.acquire(1);
}
The issue is that the first thread does NOT wake up when the first semaphore is signalled, i.e. the application produces the following output:
about to wait on semaphore 1
signaling semaphore 1
about to wait on semaphore 2
And that's it. The first thread no longer wakes up.
Now I change the first thread to do the following:
Thread1 {
print("about to wait on semaphore 1");
while (!sem1.tryAcquire(1, 200));
print("finished waiting on semaphore 1");
sem2.release(1);
}
In this case the first thread sleeps for at most 200ms before it tries to acquire the semaphore again. Now I get the following error:
QWaitCondition::wait(): mutex unlock failure: Invalid argument
No other mutexes or other synchronisation primitives are used by the application. What could be the issue?
Update:
I've removed the Semaphores and replaced each with a QWaitCondition and a QMutex and now it works just fine. I didn't make any other changes and I still don't know why the version with semaphores was incorrect. They were both initialised to 0.
Probably you do something wrong somewhere else (e.g., semaphore initialization code).
The following example compiles and runs (gcc).
threads.h:
#pragma once
#include <QThread>
class Thread1 : public QThread
{
protected:
virtual void run();
};
class Thread2 : public QThread
{
protected:
virtual void run();
};
threads.cpp:
#include "threads.h"
#include <QSemaphore>
#include <iostream>
namespace
{
QSemaphore sem1, sem2;
}
void Thread1::run()
{
std::cout << "about to wait on semaphore 1\n";
sem1.acquire(1);
//while (!sem1.tryAcquire(1, 200)); //works too
std::cout << "finished waiting on semaphore 1\n";
sem2.release(1);
}
void Thread2::run()
{
std::cout << "signaling semaphore 1\n";
sem1.release(1);
std::cout << "about to wait on semaphore 2\n";
sem2.acquire(1);
}
main.cpp:
#include "threads.h"
#include <iostream>
int main(int argc, char *argv[])
{
Thread1 t1;
Thread2 t2;
t1.start();
t2.start();
t1.wait();
t2.wait();
std::cout << "Success\n";
}
possible output:
signaling semaphore 1
about to wait on semaphore 2
about to wait on semaphore 1
finished waiting on semaphore 1
Success

Incrementing a global variable with a thread

I just wrote the following code to understand better how Threads work:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int globalVariable = 1;
void *myfunc (void *myvar);
int main (void) {
pthread_t thread1;
int waitms;
while(globalVariable <= 50){
printf("Main function: %d \n", globalVariable);
if (globalVariable==9) {
pthread_create(&thread1, NULL, myfunc, NULL);
pthread_join(thread1, NULL);
}
usleep(300000);
globalVariable++;
}
return 0;
}
void *myfunc (void *myvar){
int waitms;
while(globalVariable<=50) {
printf("Thread1: %d \n", globalVariable);
usleep(300000);
globalVariable++;
}
return 0;
}
The code must print a value of a global variable that is incremented in the main function. When this variable has the value 9, the main function calls a thread, that does the same as the original main function, but without calling another thread.
In the Output I get the first 9 prints of the main function and all the following ones are from the thread. Shouldn't they be mixed? What have I done wrong?
No because you are joining the thread1, so the main thread blocks until thread1 dies. Once thread1 dies it resumes but thread1 has incremented the globalVariable to a point where the main thread exits the first while loop.
Removing the join you will see mixed results, better still would be to move the join outside of the while loop so if thread1 is still alive when the main thread exits the loop it waits... it's most likely going to dead by that time but you should make sure your child threads have finished up before exiting the main thread.

Resources