Alright, so this question isn't exactly about thread management... well, sort of. I am looking for different solutions to this configuration. I have a few ideas, but am looking for any solutions that could satisfy the problem. And will weigh the pros and cons to implement the best one.
Here is the situation.
I have a manager application that will spawn a threads. This thread will continuously run and handle serial communication with boards that are connected to the system via USB. The manager application facilitates communication between other applications running on the system and this thread. The thread needs to really perform two things:
My initial design was a simple one and works. I use a queue and a mutex for manager to thread communication. So the logic of the thread is as follows:
The problem is I did not consider CPU utilization. 99.9% of the time my thread is processing nothing and just sucking up power. I need to implement a way to sleep this thread until it has work to do. So a couple ideas:
Use select() to block. This can block based on the timer I need to use, and I could change the queue messaging implementation to socket messaging. So instead, the thread would open a client socket to the manager and the manager would pass the messages over the socket to the thread. Then select() would sleep until there was activity on the fd or my timer was up.
Pro: Exactly the functionality I need.
Con: Aren't sockets a bit heavy processing for communication to a thread where you share memory already?
Use a signal system. (Someone more knowledgeable in Linux can pipe up here with an implementation example... I'm not sure exactly how to do it.) But the thread could sleep for the duration of the timer, and wake up to process if a signal was received from the manager.
Pro: Maintains current implementation using shared memory
Con: Not sure how to implement. Is there a function like select() that works with signals instead of fds?
Potentially a mutex. I could block until a mutex was posted to by the manager.
Pro: Still sharing memory
Con: might need to move timer processing to the manager and that really isn't an option as it has other timers and critical work to perform.
Please recommend and feel free to critique. I am open to any efficient options. Please note though this is running on an embedded system, so resources usage is critical.
sleep() Method: Method Whenever Thread. sleep() functions to execute, it always pauses the current thread execution. If any other thread interrupts when the thread is sleeping, then InterruptedException will be thrown.
sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.
A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time: Thread.
Thread Sleep (sleep_for & sleep_until) C++ 11 provides specific functions to put a thread to sleep. Description: The sleep_for () function is defined in the header <thread>. The sleep_for () function blocks the execution of the current thread at least for the specified time i.e. sleep_duration.
The classical tool to handle such situations are semaphores and not mutexes or condition variables. Think of them as tokens passed from the manager to the thread.
The thread could use sem_timedwait
to be sure to wake up once in a while to check for data.
Beware to capture the error returns of sem_
functions well, they are interruptible. So you may have a bit more wake ups than you would think.
Try something like this, using semaphores:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t s_sem;
static int iAlive = 1;
void* thFunc(void *param)
{
printf("%s : ENTER \n", __FUNCTION__);
while(iAlive)
{
printf("%s : waiting \n", __FUNCTION__);
sem_wait(&s_sem);
printf("%s : got a signal - doing something \n", __FUNCTION__);
sleep(1);
}
printf("%s : EXIT \n", __FUNCTION__);
return 0;
}
int main()
{
pthread_t thread;
sem_init(&s_sem, 0, 0);
if(0 != pthread_create(&thread, NULL, thFunc, NULL))
{
printf("%s : pthread_create FAILED \n", __FUNCTION__);
return -1;
}
while ( getchar() != 'q' )
{
printf("%s : sending signal \n", __FUNCTION__);
sem_post(&s_sem);
}
iAlive = 0;
sem_post(&s_sem);
pthread_join(thread, NULL);
sem_destroy(&s_sem);
return 0;
}
You can replace sem_wait
with sem_timedwait
if you need a timeout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With