ProgrammingThis 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.
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.
#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.
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?"
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!
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...
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.
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...
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.
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.