Sleep for N seconds and wait for keypress - c

I want to write a program in C that performs some function and then sleeps for some minutes.
During this sleep period I would like to do something and exit if a key is pressed.
int main()
{
while(1)
{
/*body*/
sleep(300);
}
/*some lines here*/
return 0;
}
Is there anyway that I can exit the loop during either the sleep period or at any time using a non-blocking key listener?

Just don't sleep for 300 seconds but rather 300 x for 1 second and check for key press:
int main()
{
while(1)
{
/*body*/
for ( int i=0; i<300; i++ )
{
if (keypressed())
doSomething();
}
}
/*some lines here*/
return 0;
}
EDIT: Why the while (1) in your code? Do you really want to run your program endlessly? (In that case, /*some lines here*/ doesn't make sense.)

there are several possible solutions:
use a timed select
use 2 threads - one waiting on the input and the other sleeping and doing the operation
As #Axel suggested, split the big sleep to several smaller sleep. To get an interval smaller than 1 sec, you can use usleep() or nanosleep()
The simplest solution would probably be 3, but is slightly less efficient, as it's using polling instead of event driven

During this sleep period I would like to do something and exit if a key is pressed. - It is not possible.
Because during the sleeping period Process will go to suspend state. Once the process suspended, you cant do anything until it woke up again. In that sleeping time if you pressed any keys also your process won't come to know which what happened? or what key is pressed?. Because already Your process is suspended.
And in your code why you are using while(1)? -
while(1)
{
/*body*/
sleep(300);
}
/*some lines here*/ // Your program wont execute this part. Because you have while(1) before. It wont comes out of the loop.

Related

Why does these two threads not run synchronously?

I have the following program that spawns two threads to print_something() and they both repeatedly print a specific string: thread 1 prints "Hi\n" and thread 2 prints "Bye\n":
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_something(int *k)
{
int n = 100;
int i;
if (*k) {
for (i = 0; i < 100; i++) {
printf("Hi\n");
}
} else {
for (i = 0; i < 100; i++) {
printf("Bye\n");
}
}
}
int main()
{
int x = 1, y = 0;
pthread_t t1, t2;
pthread_create(&t1, NULL, print_something, &x);
pthread_create(&t2, NULL, print_something, &y);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("End of program.\n");
return 0;
}
I expected them to run synchronously wherein the output in the terminal would be random such as:
Hi
Hi
Bye
Hi
Bye
...
But instead I always get thread 1 to finish its printing first before thread 2 will start printing:
Hi
Hi
...
Hi
Hi
Bye
Bye
...
Bye
Bye
End of program.
Why is the first thread blocking the second thread from printing?
Why is the first thread blocking the second thread from printing?
Who says it's blocking? Maybe starting a new thread takes long enough that the first additional thread (running in parallel with the original thread) finishes its printing (to stdout's buffer) before the second additional thread arrives at the point of trying to print anything.
On the other hand, POSIX does specify that the stdio functions perform operations on streams as if there was a lock associated with each stream that a thread must obtain upon entry to the function and releases upon exit. Thus, the first thread may indeed be blocking the second via the lock associated with stdout.
Moreover, when a thread unlocks a lock and then immediately tries to re-acquire the same lock, there is a high probability for that thread to succeed immediately despite other threads contending for the lock. As a result, when an entire loop body starts with acquiring a lock and ends with releasing that lock -- as is the case in your code for the lock associated stdout -- it is common for one thread to be able to monopolize the lock for many loop iterations.
I expected them to run synchronously wherein the output in the terminal would be random such as:
That's an unreasonable expectation. If two people each need to put in a hundred screws and are sharing a screwdriver, do you think they should hand off the screwdriver after each screw? It only makes sense to hand off the screwdriver when the one holding the screwdriver is tired.
Each thread spends the vast majority of its time accessing the console output stream. It can only do this by excluding the other thread. The behavior you expect would be atrocious.
Would they run on the same core? That would require a context switch after every line of output -- the worst performance possible for this code. Would they run on two cores? That would mean each core is waiting for the other core to finish with the console for about half the time -- also horrible performance.
Simply put, you expected your system to find a terrible way to do what you asked it to do. It found a much more efficient way -- letting one thread keep the console, finish what it was doing, and then letting the other go.

How to I interrupt sleep()

So, I have a while(1) loop with a sleep(60) seconds at the end. The problem is, my program can receive an instruction in the meantime, but will have to wait the 60 seconds until it's executed. I've tried with a handler and my other program sending a signal (with kill(daemonid,SIGCONT)), but it doesn't seep to interrupt sleep() (i.e. make it return).
void handler(){
write(1,"bonjour",7);
alarm(1);
}
/*code blocks irrelevant to the question*/
int main(){
/*reads and opens files*/
struct sigaction execaction;
memset(&execaction,0,sizeof(struct sigaction));
execaction.sa_handler=handler;
sigaction(SIGCONT,&execaction,NULL);
while(1){
pf[0].fd=request_pipe;
pf[0].events=POLLIN;
int p=poll(pf,1,timeout);
if(pf[0].revents & POLLIN){
read(request_pipe,&operation,sizeof(uint16_t));
switch (operation){
case CLIENT_REQUEST_CREATE_TASK:
printf("create\n");
reply_pipe=open(path2,O_WRONLY);
rep=SERVER_REPLY_OK;
write(reply_pipe,&rep,sizeof(int));
taskid=htobe64(0);
write(reply_pipe,&taskid,sizeof(uint64_t));
close(reply_pipe);
break;
case CLIENT_REQUEST_LIST_TASKS:
printf("list\n");
reply_pipe=open(path2,O_WRONLY);
rep=SERVER_REPLY_OK;
write(reply_pipe,&rep,sizeof(int));
close(reply_pipe);
break;
default:
printf(":(");
}
}else{
printf("Timed out\n");
printf("coucou \n");
}
close(request_pipe);
int t=60;
sleep(t);
}
return 0;
}
}
So the program that writes in these pipes, at the end of every option sends a kill signal to this daemon process.I know it writes things well because after a minute it's executed.
So how can I stop sleep() in this case if I receive something in the pipe to read (and then restart it at the end of the loop)? I've tried with SIGCONT, it doesn't seem to be working.
You could implement a function that
receives the number of total seconds to sleep
breaks down the sleep 60 into 60 sleeps of 1
loops a variable between 1 and the number of seconds to sleep
on each iteration of the loop runs the function pointer to check whether the sleep process should continue
And then you can implement a function that checks whether the sleep should be ended and pass this function pointer to the function that handles the sleep along with the number of seconds to sleep.

to interrupt a sleeping thread when main thread is to exit

I have a main thread which create child threads to do various task. There is a child thread which is tasked to report on the status every 100s
My current mechanism of stopping the thread is to observe a global boolean. Somewhat like this
Child thread
void* ReportThread(bool* operation)
{
while(*operation)
{
// do its reporting task
// ........
int counter = 0;
while( counter < 100 && operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
sleepCounter += 1;
}
}
}
Parent (Main) Thread:
bool operation = false;
int main(){
pthread_t tid;
err = pthread_create(&tid), NULL, &ReportThread, &operation);
printf("Please input esc to end operation \n");
while ((ch = getchar()) != 27);
operation =true;
pthread_join(tid,NULL);
return 0;
}
The problem:
It seem that using sleep(n). The number of seconds seem very inconsistent. When the program is stopped, this thread takes a while maybe 10 second to actually stop
Is there a way to interrupt a thread to sleep? I heard you could use signal. I am coding in linux
Can I just simply just use a pthread_cancel(tid) instead of pthread_join(tid)?
Regards
This part
while( counter < 100 || operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
sleepCounter += 1;
}
is wrong.
First I assume that sleepCounter += 1; is really a typo and that it should be:
while( counter < 100 || operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
counter += 1;
}
Then the problem is that even if operation is set to false by some other thread, the while will not finish until counter reach 100.
The code should be
while( counter < 100 && operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
counter += 1;
}
Further, in main you never set operation to false. Another typo?
You don't need two while loops. And if you want to set a timer, use time functions for it, because sleep is a cancellation point and it is not guaranteed that sleep actually sleeps that amount of time.
Example:
void* ReportThread(void *args)
{
time_t start = time(NULL);
time_t now;
bool *operation = (bool*) args;
while (*operation) { //while active
now = time(NULL); //get current time
if (now - start >= 100) { //if the threshold is exceeded
start = now; //reset timer
//and probably do other stuff
}
sleep(1); //sleep for one second
}
return NULL;
}
The example above has a max lag of one second, that means if you set operation to false right at that moment when the thread entered the sleep state, you have to wait until sleep returns, only then it will recognize the modified state. The example also has the advantage, that you can easily modify the threshold value (since it depends on the 'real' time, instead of a counter and a non accurate sleep time).
Btw. the variable operation should be either an atomic boolean or protected by a mutex (since it is accessed from different threads).
To answer the questions of your problem:
should be answered by the example above
since i mentioned it before, sleep is a cancellation point, that means it gets interrupted if the process handles a signal (see man pthreads - section Cancellation points).
see man pthread_cancel - section Notes
On Linux, cancellation is implemented using signals. Under the NPTL threading implementation, the first real-time signal (i.e., signal 32) is used for this purpose. On LinuxThreads, the second real-time signal is used, if real-time signals are available, otherwise SIGUSR2 is used.
You cannot use pthread_cancel over pthread_join! You have to use pthread_join in either case (described in detail in the man page).
I don't know if this will fix all your problems, but it's a bit too much for a comment. One problem, your ReportThread function signature is wrong. It should be:
void* ReportThread(void* args);
And then in that function you need to do something like:
void* ReportThread(void* args)
{
bool* operation = (bool*)args;
while(*operation)
{
...
}
}
I'm not sure how it's working right now, but your compiler should at least be issuing a warning trying to convert a bool* type to a bool.
Also be aware of race conditions on operation

What to use pthread_join,pthread_exit or pthread_cancel while thread in sleep and need to close gracefully?

I have a thread running in while with condition and it has sleep of 2 minutes.
(i.e.
while (condition) {
//do something
sleep(120);
}
)
To terminate the thread gracefully, I used pthread_join() and made while condition to false (e.g. someflag = 0)
And its working to terminate the thread, but if the thread is sleeping, it doesn't terminate until it finishes sleeping.
This is the problem I need avoid; I need to make thread come out early even if it is in sleep.
None of the above. Instead of while (condition) sleep(120); you should be using a condition variable:
while (condition) {
...
pthread_cond_timedwait(&condvar, &mutex, &abstime);
...
}
I chose pthread_cond_timedwait assuming you actually need to wake up and do something every 120 seconds even if nobody signals you, but if not you could just use pthread_cond_wait instead. The signaling thread needs to call pthread_cond_signal(&condvar) after changing the condition, and of course all access (reads and writes) to the state the condition depends on need to be protected by a mutex, mutex. You have to hold the mutex while calling pthread_cond_[timed]wait. If you have further questions on how to use condition variables, search the existing questions/answers (there are lots) or ask a follow-up.
This may not be the right answer, however I can suggest a work around to break sleep() of 120 sec into smaller time such as 2 seconds and put that in loop. Every time the loop executes, you can check for condition e.g.
while (condition)
{
//do something
int i = 0;
while(condition && (60 > i))
{
sleep (2);
i++;
}
}
I hope someone will surely paste better answer.

Wake up a sleeping thread, else sleep for N seconds

I am writing a C program using POSIX threads.
Let N be a global variable. I have a thread that calls sleep(N). A different thread then changes the value of N. How can I have my original thread that called sleep(N) wake up, and call sleep again on the new value of N?
To rephrase, I want to sleep for N, if N gets updated, wake up, and sleep for the new value of N.
I have looked into pthread_cond_wait and pthread_cond_timedwait, but I do not think it is useful in my case, as I would need the threads to be asleep for a specific amount of time. I need my thread to continuously sleep and wake up every N seconds.
As user1930928 showed below, I think I need to use pthread_cond_timedwait
The question and the objective is stil not clear to me...but let me provide a code skeleton so that you can clarify your question better.
Initialize N.
Initialize mutex.
Initialize CV.
T1()
{
mutex_lock();
while (1) {
copy_of_N = N;
pthread_cond_timedwait(N); // drops the mutex
....
....
// timed wait done OR wakeup was issued on cond var
if (copy_of_N != N) {
// N was changed
do_something();
} else {
// N was not changed
do_something_else();
}
// either way, goto sleep on N.
}
mutex_unlock();
}
T2()
{
mutex_lock();
change N;
pthread_cond_signal();
mutex_unlock();
}
Please clarify your question based on whether the above skeleton matches your req or not.

Resources