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 |
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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
|
 |
|
03-26-2011, 05:55 PM
|
#16
|
Senior Member
Registered: May 2005
Posts: 4,481
|
Quote:
Originally Posted by nime
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.
|
03-26-2011, 06:01 PM
|
#17
|
Senior Member
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
|
Quote:
Originally Posted by Sergei Steshenko
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
To suspend a process one has to use 'sleep' or 'usleep' - the latter for fractional second if/when needed.
|
Agreed.
|
|
|
03-26-2011, 06:17 PM
|
#18
|
Senior Member
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
|
Quote:
Originally Posted by nime
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
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.
|
|
|
03-26-2011, 08:06 PM
|
#19
|
Senior Member
Registered: May 2005
Posts: 4,481
|
Quote:
Originally Posted by Nominal Animal
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'.
|
|
|
03-27-2011, 05:27 AM
|
#20
|
Senior Member
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
|
Quote:
Originally Posted by Sergei Steshenko
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,
|
|
|
03-27-2011, 02:22 PM
|
#21
|
Senior Member
Registered: May 2005
Posts: 4,481
|
Quote:
Originally Posted by Nominal Animal
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.
|
|
|
03-27-2011, 03:24 PM
|
#22
|
Senior Member
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
|
Quote:
Originally Posted by Sergei Steshenko
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.
|
|
|
03-27-2011, 04:48 PM
|
#23
|
Senior Member
Registered: May 2005
Posts: 4,481
|
Quote:
Originally Posted by Nominal Animal
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 ?
|
|
|
03-27-2011, 07:33 PM
|
#24
|
Senior Member
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
|
Quote:
Originally Posted by Sergei Steshenko
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.
|
|
|
03-27-2011, 09:42 PM
|
#25
|
Senior Member
Registered: May 2005
Posts: 4,481
|
Quote:
Originally Posted by Nominal Animal
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 ?
|
|
|
03-28-2011, 05:38 AM
|
#26
|
Senior Member
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
|
Quote:
Originally Posted by Sergei Steshenko
|
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
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.
|
All times are GMT -5. The time now is 01:27 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|