Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm trying to create a signal handler thread to handle SIGALRM signals.
The main thread calls the following function before creating any other threads
Code:
pthread_t Timer::Init(long _clock_interval_musec)
{
// Set interval.
clock_interval = _clock_interval_musec;
// This is called while in a single threaded environment.
// Main thread masks alarm.
sigset_t alarm_off_mask;
if ((sigemptyset(&alarm_off_mask) == -1) || (sigaddset(&alarm_off_mask, SIGALRM) == -1))
perror("Failed to initialize the signal set");
if (pthread_sigmask(SIG_BLOCK, &alarm_off_mask, NULL) == -1)
perror("Failed to block SIGALRM");
// Now call a new thread which handles alarm signals.
pthread_t retID;
pthread_create(&retID, NULL, TimerHandlerThread, NULL);
// Return id of thread responsible for managing alarm signals.
return retID;
}
As you can see, I block the alarm signal.
The spawned signal handler thread has the following Run function
Code:
void* Timer::TimerHandlerThread(void* args)
{
// Change granualirity of alarm.
itimerval tv;
tv.it_interval.tv_sec = clock_interval / USECS_IN_SECS;
tv.it_interval.tv_usec = clock_interval % USECS_IN_SECS;
setitimer(ITIMER_REAL, &tv, NULL);
// Unmask alarm signals in this thread.
sigset_t sigset;
if ((sigemptyset(&sigset) == -1) || (sigaddset(&sigset, SIGALRM) == -1))
perror("Failed to add signal to wait for");
Timer currentTime;
int sig;
while (1)
{
/* wait for a signal to arrive */
sigwait(&sigset, &sig);
std::cout << "we are here\n";
if (sig == SIGALRM && g_timerQueue.size() > 0)
{
currentTime.Set(0);
// Handle if needed
g_mutex.P();
if (*(g_timerQueue.front()) < currentTime)
{
g_timerQueue.front()->Event_Handler();
std::pop_heap(g_timerQueue.begin(), g_timerQueue.end());
g_timerQueue.pop_back();
}
g_mutex.V();
}
}
return NULL;
}
Sigwait never returns ("we are here" never prints).
clock_interval is 50.
Is the timer not firing?
Did I not set my interval correctly?
Did I not proper block the signals ensuring the that the default handler would not take care of them?
I'd suggest you ask the mods (via the report button) to move this to the Programming section for better/faster help.
I wouldn't mind that at all. I just figured the newbie section was proper for me since I've only started reading, nevermind programming, on Unix a week ago. Here is the code as it stands now by the way
Code:
void* Timer::TimerHandlerThread(void* args)
{
// Change granualirity of alarm.
itimerval tv;
tv.it_value.tv_sec = tv.it_interval.tv_sec = clock_interval / USECS_IN_SECS;
tv.it_value.tv_usec = tv.it_interval.tv_usec = clock_interval % USECS_IN_SECS;
if (setitimer(ITIMER_REAL, &tv, NULL) == -1)
perror("Failed to set timer interval");
Timer currentTime;
int sig;
while (1)
{
/* wait for a signal to arrive */
sigwait((const sigset_t*)args, &sig);
if (sig == SIGALRM && g_timerQueue.size() > 0)
{exit(0);
currentTime.Set(0);
// Handle if needed
g_mutex.P();
if (*(g_timerQueue.front()) < currentTime)
{
g_timerQueue.front()->Event_Handler();
std::pop_heap(g_timerQueue.begin(), g_timerQueue.end());
g_timerQueue.pop_back();
}
g_mutex.V();
}
}
return NULL;
}
pthread_t Timer::Init(long _clock_interval_musec)
{
// Set interval.
clock_interval = _clock_interval_musec;
// This is called while in a single threaded environment.
// Main thread masks alarm.
sigset_t sigset;
if (sigemptyset(&sigset) == -1)
perror("Failed to add signal to block");
if (sigaddset(&sigset, SIGALRM) == -1)
perror("Failed to add signal to block");
if (sigprocmask(SIG_BLOCK, &sigset, NULL) == -1)
perror("Failed to block SIGALRM");
// Now call a new thread which handles alarm signals.
pthread_t retID;
pthread_create(&retID, NULL, TimerHandlerThread, (void*)&sigset);
// Return id of thread responsible for managing alarm signals.
return retID;
}
It still gives me simillar problems.
Timer::Init is the first thing called in main.
Is the timer not firing?
Did I not set my interval correctly?
Did I not proper block the signals ensuring the that the default handler would not take care of them?
I cannot repeat the problem (ie it works here). Perhaps look at the following:
1. print out the values you are storing in the timing counters tv_sec/tv_usec
2. make sure that the main thread is not exiting (since its return will end the program)
3. it isn't clear why you are creating the currentTime object on the stack inside the TimerHandlerThread member function
I cannot repeat the problem (ie it works here). Perhaps look at the following:
1. print out the values you are storing in the timing counters tv_sec/tv_usec
2. make sure that the main thread is not exiting (since its return will end the program)
3. it isn't clear why you are creating the currentTime object on the stack inside the TimerHandlerThread member function
1. They are fine.
2. It's exiting gracefully, the threads run just fine in the background. In fact, the thread runs, it just blocks in sigwait.
3. It doesn't matter.
I implemented the same signal handling technique with sigaction and it works. It's just more writing and less elegant. =/
It's exiting gracefully, the threads run just fine in the background
My point was that the threads will die if the code exits from main. Since you didn't include that bit of the code, it wasn't clear. It also isn't clear how you have declared the member functions (I'm assuming the thread function must be static).
I have only tested your code under Linux and it works okay (ie, the signal is caught by the sigwait and it reaches the next lines). You might be on a different system (BSD?).
My point was that the threads will die if the code exits from main. Since you didn't include that bit of the code, it wasn't clear. It also isn't clear how you have declared the member functions (I'm assuming the thread function must be static).
I have only tested your code under Linux and it works okay (ie, the signal is caught by the sigwait and it reaches the next lines). You might be on a different system (BSD?).
I was running under BSD first, but I wasn't aware it would have not worked. But like I said... the sigaction "version" works perfectly. =/
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.