Multithreaded Environment - Signal Handling in c++ in unix-like environment (freeBSD and linux) - linux

I wrote a network packet listener program and I have 2 threads. Both runs forever but one of them sleeps 30 sec other sleeps 90 sec. In main function, I use sigaction function and after installed signal handler, I created these 2 threads. After creation of threads, main function calls pcaploop function, which is infinite loop. Basic structure of my program:
(I use pseudo syntax)
signalHandler()
only sets a flag (exitState = true)
thread1()
{
while 1
{
sleep 30 sec
check exit state, if so exit(0);
do smth;
}
}
thread2()
{
while 1
{
sleep 90 sec
check exit state, if so exit(0);
do smth;
}
}
main()
{
necassary snytax for sigaction ;
sigaction( SIGINT, &act, NULL );
sigaction( SIGUSR1, &act, NULL );
create thread1;
create thread2;
pcaploop(..., processPacket,...); // infinite loop, calls callback function (processPacket) everytime a packet comes.
join threads;
return 0;
}
processPacket()
{
check exitState, if true exit(0);
do smth;
}
And here is my question. When I press CTRL-C program does not terminate. If the program run less than 6-7 hours, when I press CTRL-C, program terminates. If the program run 1 night, at least 10 hours or more, I cannot terminate the program. Actually, signal handler is not called.
What could be the problem? Which thread does catch the signal?

Basically it would be better to remove all pseudo code you put in your example, and leave the minimum working code, what exactly you have.
From what I can see so far from your example, is that the error handling of sigaction's is missing.
Try to perform checks against errors in your code.

I am writing this for those who had faced with this problem. My problem was about synchronization of threads. After i got handle synchronization problem, the program now, can handle the signals. My advice is check the synchronization again and make sure that it works correctly.
I am sorry for late answer.
Edited :
I have also used sigaction for signal handling
and I have change my global bool variable whit this definition :
static volatile sig_atomic_t exitFlag = 0;
This flag has been used for checking whether the signal received or not.

Related

How an exit code is determined in a multithreaded program when one of the threads fails?

struct func
{
int& i;
func(int& i_):i(i_){}
void operator()()
{
for (unsigned j = 0; j < 1000000; ++j)
{
++i;
}
}
};
int main()
{
int some_local_state = 0;
func my_func(some_local_state);
std::thread my_thread(my_func);
my_thread.detach();
return 0;
}
Output is
(process 1528) exited with code -1073741819
What determines the exit code? What does detaching mean for a Windows process?
In this example, the error code -1073741819 (0xc0020001) is not produced by your executable but by the operating system which decided to kill your process.
You also asked a question (in the comments) about detaching a thread.
This means that you will not use join() on this thread, thus you launch it, but you are not interested in knowing when it finishes its work.
EDIT
In my first answer I misread the example and thought the abrupt termination was due to an invalid memory access through the
uninitialized i reference.
It was wrong since i is actually initialised in order to reference some_local_state.
However, when main() returns some_local_state does not exist anymore while being still referenced by the thread.
Nothing is said about what happens to the detached thread at the exact moment when main() returns.
Does this thread terminate immediately before the local variables of main() disappear? I really have doubts about this...
This probably explains the abnormal termination of the process.

What is the purpose of putting a thread on a wait queue with a condition when only one thread is allowed to enter?

On this request
ssize_t foo_read(struct file *filp, char *buf, size_t count,loff_t *ppos)
{
foo_dev_t * foo_dev = filp->private_data;
if (down_interruptible(&foo_dev->sem)
return -ERESTARTSYS;
foo_dev->intr = 0;
outb(DEV_FOO_READ, DEV_FOO_CONTROL_PORT);
wait_event_interruptible(foo_dev->wait, (foo_dev->intr= =1));
if (put_user(foo_dev->data, buf))
return -EFAULT;
up(&foo_dev->sem);
return 1;
}
With this completion
irqreturn_t foo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
foo->data = inb(DEV_FOO_DATA_PORT);
foo->intr = 1;
wake_up_interruptible(&foo->wait);
return 1;
}
Assuming foo_dev->sem is initially 1 then only one thread is allowed to execute the section after down_interruptible(&foo_dev->sem) and threads waiting for that semaphore make sense to be put in a queue.(As i understand making foo_dev->sem greater than one will be a problem in that code).
So if only one passes always whats the use of foo_dev->wait queue, isnt it possible to suspend the current thread, save its pointer as a global *curr and wake it up when it completes its request?
Yes, it is possible to put single thread to wait (using set_current_state() and schedule()) and resume it later (using wake_up_process).
But this requires writing some code for check wakeup conditions and possible absent of a thread to wakeup.
Waitqueues provide ready-made functions and macros for wait on condition and wakeup it later, so resulted code becomes much shorter: single macro wait_event_interruptible() processes checking for event and putting thread to sleep, and single macro wake_up_interruptible() processes resuming possibly absent thread.

How does pthread mutex unlock work? And do threads come up at the same time?

I wanna ask you some basic thing but it really bothers me a lot.
I'm currently studying 'pthread mutex' for system programming and as far as I know, when 'pthread_mutex_lock' is called only current thread is executed not any others. Can I think like this?
And when it comes to 'pthread_mutex_unlock', when this function is called, does the current thread pass the lock permission to others and wait until some other thread calls unlock function again? Or does every thread including current thread execute simultaneously until one of them calls lock function?
Here's the code I was studying:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
enum { STATE_A, STATE_B } state = STATE_A;
pthread_cond_t condA = PTHREAD_COND_INITIALIZER;
pthread_cond_t condB = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *threadA()
{
printf("A start\n");
int i = 0, rValue, loopNum;
while(i<3)
{
pthread_mutex_lock(&mutex);
while(state != STATE_A)
{
printf("a\n");
pthread_cond_wait(&condA, &mutex);
}
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&condB);
for(loopNum = 1; loopNum <= 5; loopNum++)
{
printf("Hello %d\n", loopNum);
}
pthread_mutex_lock(&mutex);
state = STATE_B;
printf("STATE_B\n");
pthread_cond_signal(&condB);
pthread_mutex_unlock(&mutex);
i++;
}
return 0;
}
void *threadB()
{
printf("B start\n");
int n = 0, rValue;
while(n<3)
{
pthread_mutex_lock(&mutex);
while (state != STATE_B)
{
printf("b\n");
pthread_cond_wait(&condB, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Goodbye\n");
pthread_mutex_lock(&mutex);
state = STATE_A;
printf("STATE_A\n");
pthread_cond_signal(&condA);
pthread_mutex_unlock(&mutex);
n++;
}
return 0;
}
int main(int argc, char *argv[])
{
pthread_t a, b;
pthread_create(&a, NULL, threadA, NULL);
pthread_create(&b, NULL, threadB, NULL);
pthread_join(a, NULL);
pthread_join(b, NULL);
}
I kind of modified some of the original parts to make sure what's going on in this code such as adding printf("A start\n"), printf("a\n") so on.
And here are some outputs:
Output 1
B start
b
A start
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
b
STATE_B
a
Goodbye
STATE_A
b
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
b
STATE_B
a
Goodbye
STATE_A
b
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
b
STATE_B
Goodbye
STATE_A
Output 2
B start
b
A start
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
STATE_B
a
Goodbye
STATE_A
b
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
STATE_B
a
Goodbye
STATE_A
b
Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
STATE_B
Goodbye
STATE_A
So I learned that when threads are called, they are called simultaneously. Based on this logic, I added the 'printf("A start\n")' and 'printf("B start\n")' in the beginning of the each thread function 'threadA() and threadB()'. But always 'printf("B start\n")' comes up first. If they are called at the same time, don't they have to come up alternatively, at least randomly?
Also after the first 'Hello' loop, I'm assuming 'Goodbye' message always should be earlier than 'a' since I guess the 'pthread_mutex_unlock' in ThreadA calls ThreadB and waits until ThreadB calls unlock function. I want to know how this code works.
I'm guessing I would be totally wrong and misunderstood a lot of parts since I'm a newbie in this field. But wanna get the answer. Thank you for reading this :)
when 'pthread_mutex_lock' is called only current thread is executed
not any others. Can I think like this?
I guess you can think like that, but you'll be thinking incorrectly. pthread_mutex_lock() doesn't cause only the calling thread to execute. Rather, it does one of two things:
If the mutex wasn't already locked, it locks the mutex and returns immediately.
If the mutex was already locked, it puts the calling thread to sleep, to wait until the mutex has become unlocked. Only after pthread_mutex_lock() has successfully acquired the lock, will pthread_mutex_lock() return.
Note that in both cases, the promise that pthread_mutex_lock() makes to the calling thread is this: when pthread_mutex_lock() returns zero/success, the mutex will be locked and the calling thread will be the owner of the lock. (The other possibility is that phread_mutex_lock() will return a negative value indicating an error condition, but that's uncommon in practice so I won't dwell on it)
when it comes to 'pthread_mutex_unlock', does the current thread pass
the lock permission to others and wait until some other thread calls
unlock function again?
The first thing to clarify is that pthread_mutex_unlock() never waits for anything; unlike pthread_mutex_lock(), pthread_mutex_unlock() always returns immediately.
So what does pthread_mutex_unlock() do?
Unlocks the mutex (note that the mutex must have already been locked by a previous call to pthread_mutex_lock() in the same thread. If you call pthread_mutex_unlock() on a mutex without having previously called pthread_mutex_lock() to acquire that same mutex, then your program is buggy and won't work correctly)
Notifies the OS's thread-scheduler (through some mechanism that is deliberately left undocumented, since as a user of the pthreads library you don't need to know or care how it is implemented) that the mutex is now unlocked. Upon receiving that notification, the OS will check to see what other threads (if any) are blocked inside their own call to pthread_mutex_lock(), waiting to acquire this mutex, and if there are any, it will wake up one of those threads so that that thread may acquire the lock and its pthread_mutex_lock() call can then return. All that may happen before or after your thread's call to pthread_mutex_unlock() returns; the exact order of execution is indeterminate and doesn't really matter.
I guess the 'pthread_mutex_unlock' in ThreadA calls ThreadB and waits
until ThreadB calls unlock function.
pthread_mutex_unlock() does no such thing. In general, threads don't/can't call functions in other threads. For what pthread_mutex_unlock() does do, see my description above.
pthread_mutex_lock() doesn't mean only one thread will execute - it just means that any other thread that also tries to call pthread_mutex_lock() on the same mutex object will be suspended until the first thread releases the lock with pthread_mutex_unlock().
If the other threads aren't trying to lock the same mutex, they can continue running simultaneously.
If multiple threads have tried to lock the same mutex while it is locked by the first thread, then when the mutex is released by the first thread with pthread_mutex_unlock() only one of them will be able to proceed (and then when that thread itself calls pthread_mutex_unlock(), another waiting thread will be able to proceed and so on).
Note that a thread waiting for a mutex to be unlocked will not necessarily start executing immediately upon the mutex being unlocked.

Non-repeatable affinity for pthreads

I am trying to measure the time it takes for a thread from creation to actually start.
Using POSIX thread on a Debian 6.0 machine with 32-cores (no hyper-threading) and calling pthread_attr_setaffinity_np function to set the affinity.
In a loop, I am creating the threads, waiting for them to finish, repeatedly.
So, my code looks like the following (thread 0 is running this).
for (ni=0; ni<n; ni++)
{
pthread_t *thrds;
pthread_attr_t attr;
cpu_set_t cpuset;
ths = 1; // thread starts from 1
thrds = malloc(sizeof(pthread_t)*nt); // thrds[0] not used
assert(!pthread_attr_init(&attr));
for (i=ths; i<nt; i++)
{
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
CPU_ZERO(&cpuset);
CPU_SET(i, &cpuset); // setting i as the affinity for thread i
assert(!pthread_attr_setaffinity_np(&attr,
sizeof(cpu_set_t), &cpuset));
assert(!pthread_create(thrds+i, &attr, DoWork, i));
}
pthread_attr_destroy(&attr);
DoWork(0);
for (i=ths; i<nt; i++)
{
pthread_join(thrds[i], NULL);
}
if (thrds) free(thrds);
}
Inside the thread function, I am calling sched_getcpu() to verify that the affinity is working. The problem is, this verification only passes the first iteration of i-loop. For the second iteration, thrd[1] gets the affinity of nt-1 (instead of 1) and so on.
Can anyone please explain why? And/or how to fix it?
NOTE: I found a workaround that if I put the master thread to sleep for 1 second after the join finishes at each iteration, the affinity works correctly. But this sleep duration could different on other machines. So still need a real fix for the issue.

C++ Block thread exit signal/function

I have problem with blocking exit function in thread.
DWORD WINAPI thread1Func( LPVOID lpParam )
{
exit(0); // Problem is there
while(true){
printf("runnging");
Sleep(1000);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int thread1 = 1;
HANDLE thread1Handle = 0;
thread1Handle = CreateThread( 0, 0,
thread1Func, &thread1, 0, NULL);
WaitForSingleObject(thread1Handle,0);
system("pause");
return 0;
}
Unfortunately the thread which I have created in main function calls exit(0) function.
thread1Func doesn't call exit(0) statement directly. it is called by functions which has been called by thread1Func. So I cannot comment out or remove this statement.
I want to block exit signal from thread , What should I to do ?
How can I block exit signals from background threads ?
Well, exiting the process ( at least on windows ) is not the good way, so naturally you should return an error code in your main function if you can like ERROR_SUCCESS ( 0 ).
So with that being said, exit is more like a forced exit compared to what you should normally do, I can only assume that it calls ExitProcess(0) under the hood, which as you may read it on the docs for ExitProcess it does what it says, immediately exits the process without snding signals or waiting for anything ( like pending operations ), so your best bet is to exploit the DLL loading and create a a fake kernel32.dll where you block the exitprocess or whatever exit() actually calls, or do the whole thing in memory like filling the call to exit with nop's so it does nothing.
I can only assume that you are using someone else's code so that why you can't comment it out, In this case you could try some debugging helper libraries that allow you to use debugger features such as break points, and simply skip the exit if it's not coming from the main thread.

Resources