LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
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 06-30-2009, 10:18 PM   #1
ag2uki
Member
 
Registered: Oct 2004
Location: Yogyakarta, Indonesia
Distribution: Mandrake 9.0, 9.1, 9.2, 10.0
Posts: 84

Rep: Reputation: 16
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
 
Old 06-30-2009, 11:13 PM   #2
Uncle_Theodore
Member
 
Registered: Dec 2007
Location: Charleston WV, USA
Distribution: Slackware 12.2, Arch Linux Amd64
Posts: 896

Rep: Reputation: 60
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.
 
Old 07-01-2009, 02:18 AM   #3
ag2uki
Member
 
Registered: Oct 2004
Location: Yogyakarta, Indonesia
Distribution: Mandrake 9.0, 9.1, 9.2, 10.0
Posts: 84

Original Poster
Rep: Reputation: 16
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?"
 
Old 07-01-2009, 05:17 AM   #4
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 808

Rep: Reputation: 178Reputation: 178
Quote:
Originally Posted by ag2uki View Post
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.
 
Old 07-01-2009, 08:36 AM   #5
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 453Reputation: 453Reputation: 453Reputation: 453Reputation: 453
Use

Code:
fprintf(stderr, ...)
- by default stderr is autoflushed.
 
Old 07-01-2009, 09:41 AM   #6
Uncle_Theodore
Member
 
Registered: Dec 2007
Location: Charleston WV, USA
Distribution: Slackware 12.2, Arch Linux Amd64
Posts: 896

Rep: Reputation: 60
Quote:
Originally Posted by Sergei Steshenko View Post
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...
 
Old 07-01-2009, 06:52 PM   #7
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: Debian lenny, Slackware 12
Posts: 808

Rep: Reputation: 178Reputation: 178
Quote:
Originally Posted by Sergei Steshenko View Post
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 View Post
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
 
Old 07-01-2009, 07:15 PM   #8
Uncle_Theodore
Member
 
Registered: Dec 2007
Location: Charleston WV, USA
Distribution: Slackware 12.2, Arch Linux Amd64
Posts: 896

Rep: Reputation: 60
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...
 
Old 07-02-2009, 01:35 AM   #9
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
Quote:
Originally Posted by ag2uki View Post
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.
 
Old 07-02-2009, 02:01 AM   #10
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 453Reputation: 453Reputation: 453Reputation: 453Reputation: 453
Quote:
Originally Posted by Uncle_Theodore View Post
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
 
  


Reply

Tags
sleep


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
sleep & localtime query nsvora Linux - General 1 06-29-2009 11:49 PM
sleep( ) and usleep( ) problem emp1953 Linux - Newbie 2 03-13-2008 02:50 PM
usleep? kalleanka Programming 5 08-22-2006 07:01 AM
stopping usleep function allomeen Programming 4 12-19-2005 07:23 PM
Fedora3 & monitor sleep mode zeky Linux - General 1 03-16-2005 03:54 PM


All times are GMT -5. The time now is 05:44 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration