0

I wrote a small programm on my RasPI and have trouble with the sleep() and usleep() functions. both of them don't work. When I use usleep() with a number below 1000000 (below 1 second) it works, whenever i try to use a number that should let the program sleep for 1 second or more, it doesn't work. I've been working on making the Digital pin HIGH for a given time.

I've tried to shrink the program to printf() and to sleep only:

#include <stdio.h>
#include <unistd.h>

int main()
{

    while (true)
    {
        sleep(1);
        printf("%.2f", 10.1);
    }
}
Milan Š.
  • 1,353
  • 1
  • 2
  • 11
Luks
  • 19
  • 4
  • How complete is the standard library you are using? Can you `#include` `` and ``? – Ted Lyngmo Jan 05 '23 at 13:42
  • 2
    Please be more specific than "it doesn't work". Does it not sleep, sleep forever, sleep strangely, crash, ...? – molbdnilo Jan 05 '23 at 13:42
  • so, by executing the code it should print 10.1 in the console, right? well it does it's job when using usleep() up to 999999 but when i try usleep 1000000 or sleep(1) it doesn't loop the print, in fact it prints nothing in the console, just stuck in an infinite loop – Luks Jan 05 '23 at 13:44
  • same issue after including #include #include – Luks Jan 05 '23 at 13:45
  • If you remove the looping, does the issue persist? – molbdnilo Jan 05 '23 at 13:46
  • no, once i remove the loop it does work, same if i loop it and use usleep(500000) which prints it every 0.5s – Luks Jan 05 '23 at 13:47
  • And if you replace `sleep(1)` with `std::this_thread::sleep_for(std::chrono::seconds(1));` ? – Ted Lyngmo Jan 05 '23 at 13:48
  • 6
    And does the problem persist if you flush the output buffer, e.g. by `printf("%.2f\n", 10.1);` – molbdnilo Jan 05 '23 at 13:49
  • 1
    okay, works after flush, thanks – Luks Jan 05 '23 at 13:51
  • Use this example to learn some basics of how to use GDB. I was able to quickly determine that it wasn't sleeping forever using this on my PI. – Rodney Jan 05 '23 at 13:54
  • 1
    FYI `usleep` is deprecate instead use `nanosleep` – Hackaholic Jan 05 '23 at 16:19

1 Answers1

1

works after flushing the output buffer

#include <stdio.h>
#include <unistd.h>
#include <chrono>
#include <thread>


int main()
{

    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        printf("%.2f\n", 10.1);
    }
}
Luks
  • 19
  • 4
  • 1
    You can also explicitly flush it if you don't want the newline: `printf("%.2f", 10.1);` `fflush(stdout);` – Ted Lyngmo Jan 05 '23 at 14:21
  • Luks, Appending a `'\n'` dose not certainly flush `stdout`, yet commonly does. `fflush(stdout);` is certain. – chux - Reinstate Monica Jan 05 '23 at 15:20
  • @chux-ReinstateMonica appending `'\n'` forces the flush because stdout is usually line buffered by default. Buffering can be disabled at all with `setvbuf(stdout, NULL, _IONBF, 0)` (as explained in [this](https://stackoverflow.com/a/7876756/11336762) answer) – Roberto Caboni Jan 05 '23 at 16:18
  • @RobertoCaboni There is no default buffering, such as _line buffering_, setting for `stdout` specified by C. Instead your assertions seem to be based on common, though not required, behavior. There is instead much [implementation defined](https://stackoverflow.com/q/39536212/2410359) functionality. Refer to C17dr § 7.21.3 3. Yet perhaps I have read the spec incorrectly and there is something in the spec to support your claim? – chux - Reinstate Monica Jan 05 '23 at 17:48
  • @chux-ReinstateMonica no claims about `_IOLBF` default required by specification, on my side. :) It was just an assumption, probably rushed though based experience on windows/linux command shells, about it being an unofficial habit used in common environments. It was probably a rushed assertion, as (for example) I found this rule for GNU libc (see [this article](https://eklitzke.org/stdout-buffering)): stdin -> line-buffered; stdout (TTY) -> line-buffered; stdout (not a TTY) -> fully-buffered; stderr -> unbuffered. – Roberto Caboni Jan 05 '23 at 18:39
  • 1
    So, of course no default buffering is required by the standard. My point is just that every implementation must have an "init value" (init != default) and that a common implementation choice is to initialize stdouts in line buffered mode (including, apparently, the RasPI console used by the OP). Thanks to this discussion I discovered the difference between TTY/notTTY that I wasn't aware about. – Roberto Caboni Jan 05 '23 at 18:46
  • 1
    @RobertoCaboni Fair point about "line buffered mode (including, apparently, the RasPI console used by the OP". Yet to emphasize, `fflush(stdout);` is certain. That becomes more important as one targets highly portable code. – chux - Reinstate Monica Jan 05 '23 at 21:51