Boost logo

Boost Users :

Subject: Re: [Boost-users] [BOOST THREAD] Threads Spawning Unexpectedly
From: Nigel Rantor (wiggly_at_[hidden])
Date: 2009-04-27 06:55:44


Terrimane Pritchett wrote:
>
>
> On Sun, Apr 26, 2009 at 6:01 PM, Nigel Rantor <wiggly_at_[hidden]
> <mailto:wiggly_at_[hidden]>> wrote:
>
> Terrimane Pritchett wrote:/
> /
>
> /
> /
> / What made you think that the exception was being thrown becasue
> the program is multithreaded?/
>
>
> Because I have a single threaded implementation that uses
> boost::lexical_cast extensively without throwing any exceptions or
> generating any warning/errors during compilation. Secondly,
> boost::lexcial_cast does not guarantee thread safety - just as
> std::stringstream does not guarantee thread safety.

See Igor's comments on thread-safety.

The main situation where a function may not be thread-safe is where it
access shared data, I don't beleive this is the case with lexical_cast
so I'm having a problem thinking how it could cause a problem.

If it *was* using shared data then I would expect to see data errors
rather than a consistent exception being thrown.

> /Have you checked the information that the exception is returning to
> you?/
>
>
> Yes, but if there is something specific you suggest I look for I would
> like input about that.

I would wrap the call to lexical_cast in a try block that catches the
exception and writes out the data that was passed in and perhaps some of
the type information that the exception contains and is telling you.

e.g.

-------------------------------------------------------
#include <iostream>
#include <boost/lexical_cast.hpp>

using namespace std;
using namespace boost;

int main( int argc, char** argv )
{
     if( argc < 2 )
     {
         cout << "please supply an argument to convert to an int\n";
         return 0;
     }

     string data( argv[1] );

     try
     {
         int i = lexical_cast<int>( data );

         cout << "data str : " << data << "\n";
         cout << "data int : " << i << "\n";
     }
     catch( bad_lexical_cast& e )
     {
         cout << "bad lexical cast : " << e.what() << "\n";
         cout << "data : " << data << "\n";
         cout << "source : " << e.source_type().name() << "\n";
         cout << "target : " << e.target_type().name() << "\n";
     }

     return 0;
}
-------------------------------------------------------

> /Have you got the data that caused the exception?/
>
>
> Yes. The data originates in a Collada document that has been vetted as
> sound and I have used to for testing purposes elsewhere.

See above. I actually meant the specific data that caused the exception
to be thrown. i.e. The exact data that was passed to the call to
lexical_cast that threw.

> /
> /
> / Could you please elaborate as to why you think you have more
> threads than expected? How many? What other libraries are you using
> that may create threads?/
>
>
> The number of new threads that are generated is not predicable. I am
> using MSVS 2008. I can see every active thread in my application at any
> breakpoint. I can count how many threads are active and see what type
> of threads they are. I explicitly create N threads and count M threads
> where N is less than M. Immediately after I spawn my threads I halt
> execution and count how many are active and in what state they are in.
> At that point the only threads present are those I have spawned. I then
> let the app run and new threads appear which I did not explicitly create.

Okay, this is a different problem (I think).

If you're sure that your code where you spawn threads is not being
called again then I would suggest you do have an external library
spawning threads behind your back.

There is no reason that the boost threading library would be doing this.

I suppose the most thorough way of figuring this out would be to use a
debugger aftter all of your threads are spawned and set breakpoints on
your system's thread creation calls.

> I have a complete single threaded implementation which executes over the
> exact same data - boost::lexical_cast performs exactly as it should
> using that same input data.
>
> I suppose I will need you to qualify what you would consider to be hard
> evidence here.

Okay. Sorry if I sound like I doubt you, but I have no idea who you are
and skepticism is my default stance.

Just becasue a single-threaded program iteratoes over the same data
without error does not mean that lexical_cast is the culprit here, it
may simply be that you're not synchronizing some other peice of code
that eventually means lexical_cast gets fed some bad data.

> /
> Let us know how you get on with trying to track down the data that
> caused the exception to be thrown./
>
>
> I already have done this. I get data from Collada documents as
> std::strings. I print them out. I have boost::tokenizer tokenize the
> strings. I print out the tokens. I have boost::lexical_cast convert
> the tokens to plain ole data types. In the single threaded
> implementation every cast can be checked. It is more difficult with the
> multithreaded application but generally the same thing is done.

This is exactly what you need to do. You have to get the code to print
out exactly what it was trying to convert when the exception was thrown.
See above.

> Perhaps I misunderstand what data it is that you are referring to. If
> so, I'll find it out after correct my misunderstanding.

Keep us updated, I'm interested.

   n


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net