Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can printing to stdout be a problem for MT programs?

0 views
Skip to first unread message

Erol Sahin

unread,
Oct 16, 1998, 3:00:00 AM10/16/98
to

Hi All,

I'm working on a MT program on a Linux box. I've realized that if I
print a lot of messages to stdout from multiple threads, I get some
bizarre results, such as stalling of a thread suddenly and coming
back to life again.. However sometimes the problem disappears when
I remove [or reduce] prints. Can it be because multiple thread
trying to get hold of stdout getting into bizarre race conditions?
Does anybody have any experience similar to this or any comments?

I'm putting this question forward since I tend to use prints [printf()]
for debugging and hate to look for a bug which is caused by this
"debugging technique"..

Erol Sahin

--
Neurobotics Laboratory Voice: +1-617-353-1347
Dept. Cognitive and Neural Systems Fax : +1-617-353-7755
Boston University E-mail: er...@cns.bu.edu
677 Beacon St. Boston, MA 02215 USA http://cns-web.bu.edu/~erol


Boris Goldberg

unread,
Oct 22, 1998, 3:00:00 AM10/22/98
to
Erol Sahin wrote:
<
< Hi All,
<
< I'm working on a MT program on a Linux box. I've realized that if I
< print a lot of messages to stdout from multiple threads, I get some
< bizarre results, such as stalling of a thread suddenly and coming
< back to life again.. However sometimes the problem disappears when
< I remove [or reduce] prints. Can it be because multiple thread
< trying to get hold of stdout getting into bizarre race conditions?
< Does anybody have any experience similar to this or any comments?


I'm not aware of any problems with multiple threads writing to
stdout on Linux.

However, even if there are no problems, you may be seeing interleaved
output:

example:

printf("x=%d, y=%d\n", x, y);

there is no guarantee that x and y will appear on the same line

Nader Salehi

unread,
Oct 22, 1998, 3:00:00 AM10/22/98
to
Kaz Kylheku wrote:

> In article <362F6FC0...@ms.com>, Boris Goldberg <bor...@ms.com> wrote:
> > I'm not aware of any problems with multiple threads writing to
> >stdout on Linux.
> >
> > However, even if there are no problems, you may be seeing interleaved
> >output:
> >
> > example:
> >
> > printf("x=%d, y=%d\n", x, y);
> >
> >there is no guarantee that x and y will appear on the same line
>

> Surely, printf() will lock the stream object (if you use the MT safe glibc2),
> no?

Although printf() can be used in a multi-threaded environment, there is no
guarantee that the output of two printf() statements in two threads won't be
mixed. The best thing you could do is to lock the file in which you want to
write, in your case being 'stdout'. You could replace printf() with something
like the following piece of code:

int rprintf(const char *format, ...)
{
register int len;
va_list args;

va_start(args, format);

flockfile(stdout);
len = vprintf(format, args);
va_end(args);
funlockfile(stdout);
return len;
}

If you are REALLY concerned about the perfomance, there is a better code:

int rprintf(const char *format)
{
char buf[65536];
register int i, len;
va_list args;

va_start(args, format);
flockfile(stdout);
len = vsprintf(buf, format, args);
for (i = 0; i < len; i++)
putc_unlocked((int)*(buf + i), stdout);
funlockfile(stdout);
va_end(args);
return len;
}

Nader

Mark A. Crampton

unread,
Oct 23, 1998, 3:00:00 AM10/23/98
to
Kaz Kylheku wrote:
>
> In article <362F6FC0...@ms.com>, Boris Goldberg <bor...@ms.com> wrote:
> > I'm not aware of any problems with multiple threads writing to
> >stdout on Linux.
> >
> > However, even if there are no problems, you may be seeing interleaved
> >output:
> >
> > example:
> >
> > printf("x=%d, y=%d\n", x, y);
> >
> >there is no guarantee that x and y will appear on the same line
>
> Surely, printf() will lock the stream object (if you use the MT safe glibc2),
> no?

Not on Linux, or any other UNIX variant I've dealt with. UNIX is used
to it, even before threads. stdout on NT doesn't make sense unless it's
a console appliation.

Dave Butenhof

unread,
Oct 26, 1998, 3:00:00 AM10/26/98
to
"Mark A. Crampton" wrote:

For POSIX conformance, printf() must lock the process' stdio file stream. That is,
the output is "atomic". Thus, if two threads both call a single printf()
simultaneously, each output must be correct. E.g., for


printf ("%d, %d\n", 1, 2); printf ("%s, %s"\n", "abc",
"def");

you might get

1, 2
abc, def

or you might get

abc, def
1, 2

but no more "bizarre" variations. If you do, then the implementation you're using
is broken.

There is another level of complication, though, if you're talking about the
sequence of multiple printf()s, for example. E.g., if you have

printf ("%d", 1); printf ("%s", "abc");
printf (", %d\n", 2); printf (", %s\n", "def");

Then you might indeed get something like

abc1, def
, 2

POSIX adds an explicit stdio stream lock to avoid this problem, which you can
acquire using flockfile() and release using funlockfile(). For example, you could
correct that second example by coding it as

flockfile (stdout); flockfile (stdout);
printf ("%d", 1); printf ("%s", "abc");
printf (", %d\n", 2); printf (", %s\n", "def");
funlockfile (stdout); funlockfile (stdout);

Of course, if you write to the same file using stdio from separate processes,
there's no synchronization between them unless there are some guarantees about how
stdio generates the actual file descriptor write() calls from its internal
buffering. (And I don't believe their is.)

/---------------------------[ Dave Butenhof ]--------------------------\
| Compaq Computer Corporation bute...@zko.dec.com |
| 110 Spit Brook Rd ZKO2-3/Q18 http://members.aol.com/drbutenhof |
| Nashua NH 03062-2698 http://www.awl.com/cseng/titles/0-201-63392-2/ |
\-----------------[ Better Living Through Concurrency ]----------------/


Boris Goldberg

unread,
Oct 26, 1998, 3:00:00 AM10/26/98
to
Dave Butenhof wrote:


< For POSIX conformance, printf() must lock the process' stdio file
stream. That is,
< the output is "atomic". Thus, if two threads both call a single
printf()
< simultaneously, each output must be correct. E.g., for
<
< printf ("%d, %d\n", 1, 2); printf ("%s, %s"\n", "abc",
< "def");
<
< you might get
<
< 1, 2
< abc, def
<
< or you might get
< abc, def
< 1, 2
<
< but no more "bizarre" variations. If you do, then the implementation
you're using
< is broken.


Hmmm. I do get interleaved output on Solaris 2.5.1 which made me
replace printf with sprintf+puts

0 new messages