Thread overview
Indeterminate thread behavior?
Dec 10, 2004
Georg Wrede
Dec 12, 2004
Phill Thorpe
Dec 12, 2004
Ben Hinkle
Dec 12, 2004
Georg Wrede
December 10, 2004
I can run the following, usually once, and on the following runs it (usually!) segfaults before finish. If I do something else and then run it, it again runs fine the first time only.

I ran this on RedHat-9.

# import std.thread;
#
#
# int foo(void *ptr)
# {
#     for(int i=5000;i>0;i--) {
#       printf("foo....................%d\n");
#     }
#     return 0;
# }
#
# int bar(void *ptr)
# {
#     for(int i=5000;i>0;i--) {
#       printf("bar-----------------------------------------%d\n");
#     }
#     return 0;
# }
#
#
# void main()
# {
#     Thread t1 = new Thread(&foo, null);
#
#     Thread t2 = new Thread(&bar, null);
#
#
#     t1.start();
#     t2.start();
#
#     while(t1.getState() == std.thread.Thread.TS.RUNNING)
#         Thread.yield ();
# }

Obviously, foo and bar don't yield, main only checks for t1,
no threads are stopped, no errors are caught.
Still, indeterminate behavior is not what I'd expect.

Makes no difference whether I run it like

$ ./ttest
$ ./ttest > /tmp/ttest.lst
$ ./ttest | tee /tmp/ttest.lst

But running it with the same command again makes it segfault. (If you have a new computer you might have to increase the loop count, to maybe 50000, so that the first thread doesn't always finish before the second starts.)

---------------------

Another thing: the Thread class is not well documented in the docs. Even trivial things like Arrays are meticulously explained with lots of examples, but Threads don't have a single example code there!!

---------------------

Oh, and in case you haven't already tried the above, there's a typo in both printf statements. So change

#       printf("foo....................%d\n");
to
#       printf("foo....................%d\n",i);

in both places.

Now, the really interesting part (this is slightly off-topic, but I couldn't help myself): with the above faulty printf statements, the code ran exactly the same!!!! So we have ESP inbuilt in D -- it understands what you meant to write!  :-)

Maybe I should file a bug report about checking the arguments to printf at compile time? At least for literal format strings.


December 12, 2004
On Fri, 10 Dec 2004 12:08:19 +0000, Georg Wrede wrote:

> I can run the following, usually once, and on the following runs it (usually!) segfaults before finish. If I do something else and then run it, it again runs fine the first time only.
> 
> I ran this on RedHat-9.
> 
> # import std.thread;
> #
> #
> # int foo(void *ptr)
> # {
> #     for(int i=5000;i>0;i--) {
> #       printf("foo....................%d\n");
> #     }
> #     return 0;
> # }
> #
> # int bar(void *ptr)
> # {
> #     for(int i=5000;i>0;i--) {
> #       printf("bar-----------------------------------------%d\n");
> #     }
> #     return 0;
> # }
> #
> #
> # void main()
> # {
> #     Thread t1 = new Thread(&foo, null);
> #
> #     Thread t2 = new Thread(&bar, null);
> #
> #
> #     t1.start();
> #     t2.start();
> #
> #     while(t1.getState() == std.thread.Thread.TS.RUNNING)
> #         Thread.yield ();
> # }
> 
> Obviously, foo and bar don't yield, main only checks for t1,
> no threads are stopped, no errors are caught.
> Still, indeterminate behavior is not what I'd expect.
> 
> Makes no difference whether I run it like
> 
> $ ./ttest
> $ ./ttest > /tmp/ttest.lst
> $ ./ttest | tee /tmp/ttest.lst
> 
> But running it with the same command again makes it segfault. (If you have a new computer you might have to increase the loop count, to maybe 50000, so that the first thread doesn't always finish before the second starts.)
> 
> ---------------------
> 
> Another thing: the Thread class is not well documented in the docs. Even trivial things like Arrays are meticulously explained with lots of examples, but Threads don't have a single example code there!!
> 
> ---------------------
> 
> Oh, and in case you haven't already tried the above, there's a typo in both printf statements. So change
> 
> #       printf("foo....................%d\n");
> to
> #       printf("foo....................%d\n",i);
> 
> in both places.
> 
> Now, the really interesting part (this is slightly off-topic, but I couldn't help myself): with the above faulty printf statements, the code ran exactly the same!!!! So we have ESP inbuilt in D -- it understands what you meant to write!  :-)
> 
> Maybe I should file a bug report about checking the arguments to printf at compile time? At least for literal format strings.


I thought that there was nothing wrong with either printf statments, except that the %d is a waste of time.

Phill.
December 12, 2004
"Georg Wrede" <Georg_member@pathlink.com> wrote in message news:cpc3jj$12m8$1@digitaldaemon.com...
>I can run the following, usually once, and on the following
> runs it (usually!) segfaults before finish. If I do something else and then run it, it again runs fine the first time only.
>
> I ran this on RedHat-9.
>
> # import std.thread;
> #
> #
> # int foo(void *ptr)
> # {
> #     for(int i=5000;i>0;i--) {
> #       printf("foo....................%d\n");
> #     }
> #     return 0;
> # }
> #
> # int bar(void *ptr)
> # {
> #     for(int i=5000;i>0;i--) {
> #       printf("bar-----------------------------------------%d\n");
> #     }
> #     return 0;
> # }
> #
> #
> # void main()
> # {
> #     Thread t1 = new Thread(&foo, null);
> #
> #     Thread t2 = new Thread(&bar, null);
> #
> #
> #     t1.start();
> #     t2.start();
> #
> #     while(t1.getState() == std.thread.Thread.TS.RUNNING)
> #         Thread.yield ();
> # }
>
> Obviously, foo and bar don't yield, main only checks for t1,
> no threads are stopped, no errors are caught.
> Still, indeterminate behavior is not what I'd expect.
>
> Makes no difference whether I run it like
>
> $ ./ttest
> $ ./ttest > /tmp/ttest.lst
> $ ./ttest | tee /tmp/ttest.lst
>
> But running it with the same command again makes it segfault. (If you have a new computer you might have to increase the loop count, to maybe 50000, so that the first thread doesn't always finish before the second starts.)
>
> ---------------------
>
> Another thing: the Thread class is not well documented in the docs. Even trivial things like Arrays are meticulously explained with lots of examples, but Threads don't have a single example code there!!
>
> ---------------------
>
> Oh, and in case you haven't already tried the above, there's a typo in both printf statements. So change
>
> #       printf("foo....................%d\n");
> to
> #       printf("foo....................%d\n",i);
>
> in both places.
>
> Now, the really interesting part (this is slightly off-topic, but I couldn't help myself): with the above faulty printf statements, the code ran exactly the same!!!! So we have ESP inbuilt in D -- it understands what you meant to write!  :-)
>
> Maybe I should file a bug report about checking the arguments to printf at compile time? At least for literal format strings.
>
>

Try making sure all the threads are done before the end of your main function. If some threads are still running it can cause seg-v's I believe. There are some pieces of D's threading behavior that I think should be tightened up - like how to treat threads that are still running after main exits.

-Ben


December 12, 2004
In article <cphhuc$206e$1@digitaldaemon.com>, Ben Hinkle says...
>
>"Georg Wrede" <Georg_member@pathlink.com> wrote in message news:cpc3jj$12m8$1@digitaldaemon.com...
>>I can run the following, usually once, and on the following
>> runs it (usually!) segfaults before finish. If I do something
>
>Try making sure all the threads are done before the end of your main function. If some threads are still running it can cause seg-v's I believe. There are some pieces of D's threading behavior that I think should be tightened up - like how to treat threads that are still running after main exits.

Thanks! That seems to correct the problem. I inserted

#     t1.wait();
#     t2.wait();

at the very end of main.