LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-26-2011, 05:55 PM   #16
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454

Quote:
Originally Posted by nime View Post
Yes Sergei,
something is obviously missing here.

I am totally new in C and this kind of issues so I try reachable examples from net to learn C. Between others I try about 30 examples with pthreads and mutexes which are also from Posix and all of them works as expected.
Except ones which have sleep function.
This is how I know that sleep don't work for me.
But maybe here is some workaround suitable to apply to beginners.
Nominal already know which kind of help and which level of examples to give to me
If you are learning "C" on Windows - don't. If you can't/don't want to have a physical computer with a (mostly) POSIX-compliant OS, install Linux/*BSD/*Solaris in a virtual machine running in your Windows box. A good virtual machine is VirtualBox: http://www.virtualbox.org/ .

If/when you know "C" well enough, start learning its Windows dialect.

Also, always verify what the books/examples from the net are saying in C99 standard: http://www.open-std.org/JTC1/SC22/wg...docs/n1124.pdf - it is surprisingly friendly and has quite a number of example. The standard (and the books/examples from Internet) is the ultimate source of knowledge. The standard also describes standard "C" (C99 that is) library requirements.
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 03-26-2011, 06:01 PM   #17
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by Sergei Steshenko View Post
And, indeed, as I recently discovered, if I want my whole process to sleep, and use 'nanosleep', 'nanosleep' keeps 100% CPU load. I think this "came" to me with SUSE-11.1, i.e. I think previously my single-thread process was sleeping quite nicely with 'nanosleep'.
Did you check if it actually uses the CPU?

I think this is a side effect on how the CPU load average is calculated on Linux: load includes processes blocking on I/O. And glibc probably implements nanosleep() via timerfd_create et al, in which case the "sleeping" is just blocking on the file descriptor.

Quote:
Originally Posted by Sergei Steshenko View Post
To suspend a process one has to use 'sleep' or 'usleep' - the latter for fractional second if/when needed.
Agreed.
 
Old 03-26-2011, 06:17 PM   #18
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by nime View Post
Unfortunately, my computer won't sleep with windows.h and winbase.h too.
Same error appears.
Note that the function declared in windows.h and winbase.h is Sleep(), with a capital S.

Quote:
Originally Posted by nime View Post
And with nap function I have this
Ah, it was my error.
Apparently nanosleep() is not implemented in the base Windows libraries, but some portability library or something. Therefore my nap() function won't work in Windows.

Could you check if this works in Windows? This one takes the number of milliseconds to sleep as an integer parameter.
Code:
#ifdef _WIN32
#include <windows.h>
#include <winbase.h>

void nap(int millisecs)
{
    if (millisecs >= 0)
        Sleep((DWORD)millisecs);

    return;
}

#else
#include <unistd.h>

void nap(int millisecs)
{
    if (millisecs < 0)
        return;

    while (millisecs > 1000000) {
        usleep(1000000000U);
        millisecs -= 1000000;
    }
    if (millisecs > 0)
        usleep((unsigned int)millisecs * (unsigned int)1000);

    return;
}
#endif
The #else section is for POSIX-compatible systems.

Last edited by Nominal Animal; 03-26-2011 at 06:18 PM. Reason: Added the last line.
 
Old 03-26-2011, 08:06 PM   #19
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Nominal Animal View Post
Did you check if it actually uses the CPU?

I think this is a side effect on how the CPU load average is calculated on Linux: load includes processes blocking on I/O. ...
Indirectly I can tell the CPU was truly loaded. It's an audio application, so with high CPU load due to 'nanosleep' xruns occur much more frequently and due to much lower additional load on the system.

With 'usleep' I can feel a lot of headroom, i.e. I need to really stress the OS hard in order to get xruns. The load is below 10%, so this all looks consistent to me.

And overall desktop feels more responsive with 'usleep' in my app instead 'nanosleep'.
 
Old 03-27-2011, 05:27 AM   #20
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by Sergei Steshenko View Post
Indirectly I can tell the CPU was truly loaded.
That indicates a real bug in the C library, or the kernel, or their interaction.

You see, I wrote a small test program:
Code:
#include <time.h>

int main(void)
{
    struct timespec t;

    /* Just under thirty seconds. */
    t.tv_sec = (time_t)29;
    t.tv_nsec = (long)999999999L;

    return (nanosleep(&t, NULL)) ? 1 : 0;
}
Running the above does not affect my CPU load at all, and running it under strace shows that it uses the nanosleep syscall (instead of glibc implementing it otherwise). I'm running libc6 version 2.11.1-0ubuntu7.8, and a vanilla 2.6.38 kernel.

Could you check if the above program affects your CPU load? Note that the first time you run the program, loading the libraries et cetera will create a small CPU load spike, so you should interrupt the first run early, wait a few seconds for the load to stabilize, then run it again to check if load changes at all. For me, it does not even twitch. If it does, could you run it via strace to see if it uses the syscall, or an alternate implementation? If there is a significant CPU load, and it uses the syscall, it may be a kernel bug that should be reported upstream.

Thanks,
 
Old 03-27-2011, 02:22 PM   #21
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Nominal Animal View Post
That indicates a real bug in the C library, or the kernel, or their interaction.

You see, I wrote a small test program:
Code:
#include <time.h>

int main(void)
{
    struct timespec t;

    /* Just under thirty seconds. */
    t.tv_sec = (time_t)29;
    t.tv_nsec = (long)999999999L;

    return (nanosleep(&t, NULL)) ? 1 : 0;
}
Running the above does not affect my CPU load at all, and running it under strace shows that it uses the nanosleep syscall (instead of glibc implementing it otherwise). I'm running libc6 version 2.11.1-0ubuntu7.8, and a vanilla 2.6.38 kernel.

Could you check if the above program affects your CPU load? Note that the first time you run the program, loading the libraries et cetera will create a small CPU load spike, so you should interrupt the first run early, wait a few seconds for the load to stabilize, then run it again to check if load changes at all. For me, it does not even twitch. If it does, could you run it via strace to see if it uses the syscall, or an alternate implementation? If there is a significant CPU load, and it uses the syscall, it may be a kernel bug that should be reported upstream.

Thanks,
Maybe I'll check it when I have time; my situation is different:


Code:
int main()
  {
  ...
  for(;;) // yes, an endless loop, it's a process to talk to through shared memory
    {
    if(something_needs_to_be_done)
      {
      // do what needs to be done
      }
    else
      {
      // sleep less than 1 second
      }
    }
  }
.

So, if "// sleep less than 1 second" is implemented through 'nanosleep', I have about 100% CPU load; if it is implemented through 'usleep', the load is less than 10%; in both case sleep time is the same.

I do not know whether frequent calls to 'nanosleep' matter; I think that way back when I was using SUSE-10.3 (now I have SUSE-11.1) I did have 'nanosleep' in my code and there was no high CPU load.
 
Old 03-27-2011, 03:24 PM   #22
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by Sergei Steshenko View Post
Maybe I'll check it when I have time; my situation is different:
Ok. For what it's worth, short nanosleep()s on my machine behave just as well as longer ones. There has been some changes to the Linux kernel nanosleep recently, so it's quite possible older kernels do not behave as nicely.

A likelier possibility is that your nanosleep usage may have had a small bug: if the effective nanosleep call was nanosleep({0, x}) where x is zero or negative (or > 1e9, I think), it would not sleep at all. Your loop would then eat 100% CPU like you described.
 
Old 03-27-2011, 04:48 PM   #23
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Nominal Animal View Post
Ok. For what it's worth, short nanosleep()s on my machine behave just as well as longer ones. There has been some changes to the Linux kernel nanosleep recently, so it's quite possible older kernels do not behave as nicely.

A likelier possibility is that your nanosleep usage may have had a small bug: if the effective nanosleep call was nanosleep({0, x}) where x is zero or negative (or > 1e9, I think), it would not sleep at all. Your loop would then eat 100% CPU like you described.
OK, I'm taking my claims regarding 'nanosleep' back. I've reexamined my 'nanosleep' wrapper and found an unneeded cast to 'long' (along with a needed one) which broke the code. After removing the unneeded cast the code works as "expected", i.e. CPU consumption is unnoticeable.

So, there is no need to try your code.

Still, 'nanosleep' manpage talks about suspending the calling thread and not the whole process. So, I'm not sure using 'nanosleep' to suspend a process is relying on documented behavior. Or maybe POSIX prescribes this behavior WRT the whole process and not only the calling thread ?
 
Old 03-27-2011, 07:33 PM   #24
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by Sergei Steshenko View Post
Still, 'nanosleep' manpage talks about suspending the calling thread and not the whole process. So, I'm not sure using 'nanosleep' to suspend a process is relying on documented behavior. Or maybe POSIX prescribes this behavior WRT the whole process and not only the calling thread ?
POSIX.1-2001 (also known as IEEE Std 1003.1 or Single UNIX Specification, Version 3) states that sleep, usleep and nanosleep all suspend the calling thread only. None of these suspend the entire process.

There was an error in earlier Linux man-pages (man 3 sleep stated that the entire process is suspended), but it has been corrected. See the online versions of man 3 sleep, man 3 usleep, and man 2 nanosleep.
 
Old 03-27-2011, 09:42 PM   #25
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Nominal Animal View Post
POSIX.1-2001 (also known as IEEE Std 1003.1 or Single UNIX Specification, Version 3) states that sleep, usleep and nanosleep all suspend the calling thread only. None of these suspend the entire process.

There was an error in earlier Linux man-pages (man 3 sleep stated that the entire process is suspended), but it has been corrected. See the online versions of man 3 sleep, man 3 usleep, and man 2 nanosleep.
Yes, I've just read http://pubs.opengroup.org/onlinepubs...ons/sleep.html , and it indeed says that the calling thread is suspended. So, what is the official way to suspend the whole process ?

Or maybe it is assumed that a process always has at least one thread, and for a single-threaded process there is no need to create the single thread explicitly ?
 
Old 03-28-2011, 05:38 AM   #26
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by Sergei Steshenko View Post
Yes, I've just read http://pubs.opengroup.org/onlinepubs...ons/sleep.html , and it indeed says that the calling thread is suspended. So, what is the official way to suspend the whole process ?
Putting each thread to sleep individually.

Off topic: You can also send SIGSTOP from a separate process to suspend a thread, entire process, or even a process group, but you'll need to send a SIGCONT to wake them up. SIGSTOP cannot be ignored, blocked, or catched, so you do need a separate process to send the signals.

Quote:
Originally Posted by Sergei Steshenko View Post
Or maybe it is assumed that a process always has at least one thread, and for a single-threaded process there is no need to create the single thread explicitly ?
Joe Damato has written a nice explanation here.

A normal process that does not use any threads explicitly, does always have one thread. Otherwise it cannot be executed at all.

Threads are quite basic entities for the kernel. The difference between a process that's not using threads explicitly, and one that uses threads, is that the thread library (e.g. pthread) may create additional internal structures for the threads created explicitly. For the kernel, a process is just an entity with certain identifiers and resources; all execution is done via threads.

In some pthread implementations the threading library may do time-sharing internally. The process may have many more threads than the kernel has given it, and the threading library does the internal juggling necessary for the user threads to get executed.

Off topic again: When the last thread in a process exits, all memory and resources except for process identifiers and exit status are released. Until somebody "reaps" the process using one of the wait family of functions, the process is still seen in the process list, although it is not running anymore. Reaping is one of the duties of a parent process. If the parent process has itself already died, the process will be reparented to process 1, init, which does the reaping.
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
use of sleep function in fedora shivi91 Programming 2 03-03-2011 09:17 PM
Use of Sleep function in Perl Russell Griffiths Programming 2 08-14-2006 04:37 AM
How to disable the Monitor Sleep function under RH9 ?? 242VDM242 Linux - Newbie 1 05-21-2005 01:51 PM
looking for a Sleep() function Mike Davies Linux - Software 2 10-25-2004 08:11 AM
Is the wait function is the same as the sleep function ? Linh Programming 3 04-28-2004 12:39 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:51 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration