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.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
06-30-2009, 10:18 PM
|
#1
|
|
Member
Registered: Oct 2004
Location: Yogyakarta, Indonesia
Distribution: Mandrake 9.0, 9.1, 9.2, 10.0
Posts: 84
Rep:
|
confused of using usleep & sleep
Dear all member,
I'm trying to create new C program in linux which uses usleep function. The simplified code looks like below.
Code:
#include <stdio.h>
int main(void)
{
printf("Hello world before sleep.");
usleep(2000000);
printf("Hello world after sleep.");
}
After compiling, i tried to execute it. It should print the first sentence first, then wait for 2 seconds to print the last sentences.
But, the program do not work like what exactly i want. The program waits 2 seconds to print two sentences.
I created similar program using sleep(ms) function for windows. It successfully compiled and worked properly like it should.
Please help. I have run out of time just for this.
Thank you.
ag2uki
|
|
|
|
06-30-2009, 11:13 PM
|
#2
|
|
Member
Registered: Dec 2007
Location: Charleston WV, USA
Distribution: Slackware 12.2, Arch Linux Amd64
Posts: 896
Rep:
|
Try it like this
Code:
#include <stdio.h>
int main(void)
{
printf("Hello world before sleep.\n");
usleep(2000000);
printf("Hello world after sleep.\n");
}
Does it work now? If not, try
Code:
#include <stdio.h>
int main(void)
{
printf("Hello world before sleep.\n");
fflush(stdout);
usleep(2000000);
printf("Hello world after sleep.\n");
}
You have to flush the output buffer. The first "Hello" is printer in the buffer, but gets pushed out of it only by the second "Hello".
Strictly speaking, your code should look like this:
Code:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
printf("Hello world before sleep.\n");
usleep(2000000);
printf("Hello world after sleep.\n");
return 0;
}
Last edited by Uncle_Theodore; 06-30-2009 at 11:21 PM.
|
|
|
|
07-01-2009, 02:18 AM
|
#3
|
|
Member
Registered: Oct 2004
Location: Yogyakarta, Indonesia
Distribution: Mandrake 9.0, 9.1, 9.2, 10.0
Posts: 84
Original Poster
Rep:
|
Thanks for your reply uncle theodore, it works.
So we have to flush output buffer or add new line character ("\n") at the end of the argument of printf, is not it? Humm... It's really annoying. I have not met with things like this before. If we use another programming language, we do not have to do it. For example, I wrote a similar program using Java as programming language. Then, it works properly.
Code:
public class TestSleep {
public static void main(String[] args) throws Exception {
System.out.print("Hello world before sleep.");
Thread.sleep(2000);
System.out.print("Hello world after sleep.");
}
}
It's OK. I can accept this solution. However, I still have a question in my mind, which is "why so?"
|
|
|
|
07-01-2009, 05:17 AM
|
#4
|
|
Member
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 806
Rep: 
|
Quote:
Originally Posted by ag2uki
So we have to flush output buffer or add new line character ("\n") at the end of the argument of printf, is not it? Humm... It's really annoying.
|
It's not a bug; it's a feature. It makes for more coherent output if you're generating more than one stream which goes to the screen (or to a file). To see how this might help you, run this shell script. This trivial program builds two output lines, chunk by chunk.
Code:
cat > 1.c <<EOD; gcc 1.c -o 1; ./1
#include <stdio.h>
int main(void)
{
FILE *sneeze;
sneeze=fopen("/dev/tty","w");
printf("beginning of main line; ");
fprintf(sneeze,"ahhhhhh ");
printf("end of main line\n");
fprintf(sneeze,"CHOOOO!\n");
return 0;
} /* main() */
EOD
The output:
Code:
beginning of main line; end of main line
ahhhhhh CHOOOO!
If you don't want this behavior, you have four ways around it. The first way is to use \n, as you already know. This code:
Code:
cat > 2.c <<EOD; gcc 2.c -o 2; ./2
#include <stdio.h>
int main(void)
{
FILE *sneeze;
sneeze=fopen("/dev/tty","w");
printf("beginning of main line; \n");
fprintf(sneeze,"ahhhhhh \n");
printf("end of main line\n");
fprintf(sneeze,"CHOOOO!\n");
return 0;
} /* main() */
EOD
produces this output:
Code:
beginning of main line;
ahhhhhh
end of main line
CHOOOO!
The second way is to use fflush() after all output that you want to see right away. This shell script:
Code:
cat > 3.c <<EOD; gcc 3.c -o 3; ./3
#include <stdio.h>
int main(void)
{
FILE *sneeze;
sneeze=fopen("/dev/tty","w");
printf("beginning of main line; ");
fflush(stdout);
fprintf(sneeze,"ahhhhhh ");
fflush(sneeze);
printf("end of main line\n");
fflush(sneeze); /* not necessary, because of the \n */
fprintf(sneeze,"CHOOOO!\n");
fflush(sneeze); /* not necessary, because of the \n */
return 0;
} /* main() */
EOD
produces this output:
Code:
beginning of main line; ahhhhhh end of main line
CHOOOO!
The third way, if you have only one output stream where you want automatic flushing and it's going to the screen, is to use standard error. Notice that in the following example, the sneeze is separated onto two lines, but the main output is on one line. Of course, that one line comes on the same line as the first part of the sneeze, but that's because the example insists on outputting the first part of the sneeze right away.
Code:
cat > 3.c <<EOD; gcc 3.c -o 3; ./3
#include <stdio.h>
int main(void)
{
printf("beginning of main line; ");
fprintf(stderr,"ahhhhhh ");
printf("end of main line\n");
fprintf(stderr,"CHOOOO!\n");
return 0;
} /* main() */
EOD
The output:
Code:
ahhhhhh beginning of main line; end of main line
CHOOOO!
The fourth way is to use setvbuf(). This must be done before any output to the particular stream:
Code:
cat > 5.c <<EOD; gcc 5.c -o 5; ./5
#include <stdio.h>
int main(void)
{
FILE *sneeze;
sneeze=fopen("/dev/tty","w");
setvbuf(stdout,NULL,_IONBF,0);
setvbuf(sneeze,NULL,_IONBF,0);
printf("beginning of main line; ");
fprintf(sneeze,"ahhhhhh ");
printf("end of main line\n");
fprintf(sneeze,"CHOOOO!\n");
return 0;
} /* main() */
EOD
Note that you only have to do this once per stream, and you can leave the rest of your code alone. Here's the output:
Code:
beginning of main line; ahhhhhh end of main line
CHOOOO!
Hope this helps.
|
|
|
|
07-01-2009, 08:36 AM
|
#5
|
|
Senior Member
Registered: May 2005
Posts: 4,392
|
Use
Code:
fprintf(stderr, ...)
- by default stderr is autoflushed.
|
|
|
|
07-01-2009, 09:41 AM
|
#6
|
|
Member
Registered: Dec 2007
Location: Charleston WV, USA
Distribution: Slackware 12.2, Arch Linux Amd64
Posts: 896
Rep:
|
Quote:
Originally Posted by Sergei Steshenko
Use
Code:
fprintf(stderr, ...)
- by default stderr is autoflushed.
|
This is definitely not a good thing to do, though. The output will show up on the screen, of course, but pipes and redirects will not work as they're supposed to. It's not Unix way... 
|
|
|
|
07-01-2009, 06:52 PM
|
#7
|
|
Member
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 806
Rep: 
|
Quote:
Originally Posted by Sergei Steshenko
Use
Code:
fprintf(stderr, ...)
- by default stderr is autoflushed.
|
Yes, that was the third of my four ways. I guess the penalty of having an answer that's too thorough is that it's not guaranteed that everyone will fight their way through the whole answer. :)
Quote:
Originally Posted by Uncle_Theodore
The output will show up on the screen, of course, but pipes and redirects will not work as they're supposed to.
|
Pipes won't, but redirects can:
Code:
prog1 2> redirected_stderr.txt
prog1 > redirected_stdout.txt 2> redirected_stderr.txt
prog1 2> redirected_stderr.txt | prog2
|
|
|
|
07-01-2009, 07:15 PM
|
#8
|
|
Member
Registered: Dec 2007
Location: Charleston WV, USA
Distribution: Slackware 12.2, Arch Linux Amd64
Posts: 896
Rep:
|
No, that's not what I meant. If you know that your program prints to stderr when it's not supposed to, because standard output should be printed to stdout, where it's expected, then, of course, you can redirect or do the usual stuff with piping, etc. But if someone is using your program and does NOT know that, s/he is in for a lot of trouble.
Things should be done in standard way. That's why we have standards... 
|
|
|
|
07-02-2009, 01:35 AM
|
#9
|
|
Senior Member
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,780
|
Quote:
Originally Posted by ag2uki
It's OK. I can accept this solution. However, I still have a question in my mind, which is "why so?"
|
I suppose that that depends on the implementation of the functions in the different languages. printf writes to a buffer; system.out.print does not seem to do that.
Buffered output allows the system to wait till it has some time before it's written. So it can spend time on things that are more important at that moment.
|
|
|
|
07-02-2009, 02:01 AM
|
#10
|
|
Senior Member
Registered: May 2005
Posts: 4,392
|
Quote:
Originally Posted by Uncle_Theodore
This is definitely not a good thing to do, though. The output will show up on the screen, of course, but pipes and redirects will not work as they're supposed to. It's not Unix way... 
|
It depends.
If the author needs a diagnostic message that helps him/her to debug the program it is the UNIX way.
For example, in Perl I print all my diagnostic messages through 'warn' which outputs to STDERR.
My favorite example is
Code:
cat f1.txt f2.txt f3.txt
where, say, f2.txt doesn't exist. The error message (diagnostics) goes to stderr, normal output - to stdout
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 10:07 AM.
|
|
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
|
|