After Perl 5.8.0 came out, more and more people started to use thread for various applications. I noticed that, lots of times, people use Perl thread for socket applications. That makes sense, as one thing thread does perfectly for you, is to avoid blocking.

One mistake that people make from time to time, in the threading area, is that they started to think thread is free. This includes myself. If you look at some of those examples I posted, you will see that I started to create demos which has one thread per connection on the server side.

As demos, they are probably fine, but for real applications, this is extremely harmful, and makes absolutely no sense. Thread is expensive, and really expensive.

The principle should be: only to create a new thread, when you see it as the best way to resolve blocking. As for socket application, most of the time, you can simply resolve blocking issues by using IO::Select.

Will there be a performance issue, because using less thread? No, on a single processor computer, threading does not improve performance at all, and even on multi-processor computer, threading only improves performance when you have the right number of threads. Keep in mind, at the most, there will only be one active thread really running, on any given processor, at any given time.

Recently there is this interesting thread. For last couple of days, I have been thinking about the reason, that one can only have a little bit more than 100 socket (I will soon demo to you, that the limitation is actually not about socket, but about the number of thread one can have.)

Now let’s end this post with two piece of testing code. The first piece shows how quick you will reach the maximum number of thread you can have, due to the huge cost of each thread. The second one shows you that, the limitation is really not on the socket side (of course there is a limitation for number of sockets you can have, both because limited number of valid port, and the cost of each socket, but the per socket cost is much smaller than the cost per thread.)
#!/usr/bin/perl use threads; use strict; my $count; while (1) { threads->create(\&func); print ++$count, "\n"; } sub func { while (1) { sleep(10); } }
Second piece:
#!/usr/bin/perl use IO::Socket::INET; use IO::Select; use threads; use Data::Dumper; threads->create(\&server); my $count; while (1) { my $c1 = new IO::Socket::INET(Proto => "tcp", PeerAddr => "127.1", + PeerPort => 3000) || die "Finished"; print "client socket ", ++$count, " uses local port ", $c1->sockpo +rt(), "\n"; } sub server { my $s = new IO::Socket::INET(Proto => "tcp", LocalAddr => "127.1", + LocalPort => 3000, Listen => 1); while (1) { $s->accept(); } }

Replies are listed 'Best First'.
Re: Use thread with good care, but definitely keep using it
by pfaut (Priest) on Mar 13, 2003 at 23:39 UTC
    The principle should be: only to create a new thread, when you see it as the best way to resolve blocking. As for socket application, most of the time, you can simply resolve blocking issues by using IO::Select.
    Will there be a performance issue, because using less thread? No, on a single processor computer, threading does not improve performance at all, and even on multi-processor computer, threading only improves performance when you have the right number of threads. Keep in mind, at the most, there will only be one active thread really running, on any given processor, at any given time.

    That's fine if the only thing your code is blocking on is client input but if your client's request translates into disk or database I/O, IO::Select won't allow these to overlap. Threads will. Also, if a client request turns into a long cpu-bound calculation, using threads will allow progress to be made (and possibly reported back to the client to show activity) on all outstanding requests simultaneously. Without threads, your clients would be processed serially and think nothing is happening.

    Threading is just another tool you can use to solve performance problems. There's no one tool that solves all problems. Before choosing a tool, make sure you understand the tool, its limits, and the problem you're using it on. Make sure the tool fits the situation.

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
      Agreed.

      Of course there are situations threading is the best solution. (The only reason I particularly mentioned IO::Select, is just a direct thought concerning that thread I mentioned in my original post.)

      I think, whenever threading might be a good solution, we should give it a try. At the same time, design carefully. Perl thread is still experimental, but if nobody use it, how can we gather results, gain experience, and provide constructive feedback to the the designers of Perl (itself).

      I expect lots of different replies to this post, some might even sound directly against each other. But if we consider the fact that, each reply has a different focus, you would realize that those differences actually support each other, help to form the entire picture.

      Agree with you that, just like any other tools or functions in Perl, you have to use it wisely to resolve the "right" problems.

Re: Use thread with good care, but definitely keep using it
by theorbtwo (Prior) on Mar 13, 2003 at 23:51 UTC

    pg, you point to the huge cost of threads, but you don't point out what platform you're on. There's little agreement exactly what a thread is, and how expensive it should be, between platforms. Interestingly, the way I hear it, the closer a thread is to a new process, the /cheaper/ it tends to be. Then again, I've done very little thread programming, and have real access to only win32 and linux/x86.


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

      Yes, the results would be different on different platforms, especialy for something like thread. As you pointed out, the thread implementations are so different on different platforms.

      Even on similar platforms, with a different configuration, the results are so different. I tried:
      1. windows 2k, with a high configuration (not sure about the exact numbers, I am at home now, and that one is at my company). After created 230 threads, the first script exited without error or warning, but quited.
      2. with this win98 at home, low configuration - 32m memory, it quited after 30 threads being created.
      On windows, I would expect the setting of virtual memory might alter the results.

      I think lots of people probably want to see results on other platforms, as future reference. I have access to unix, but it only has 5.6.1 installed, so useless in this case.

        WinXP corp (pro), 640MB RAM, AS 5.8.0 (build 804) dies after approx 333 threads, trying to write to memory at virtual address 4 -- clearly a bug. At that point, I'm 540 MB into swap, going down to 405MB after hitting "OK" to the debug or die dialog box (a dfferance of 135MB, but that doesn't neccessarly mean all that much), and the threads took an average of 1/30s to create (I modified your code slightly).

        BTW, anybody know if I should perlbug for this, or is this likely to be unrecognizably changed in bleadperl anyway?


        Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

Re: Use thread with good care, but definitely keep using it
by Revelation (Deacon) on Mar 14, 2003 at 00:02 UTC
    Please note that for backwards compatibility threading is not an option (especially with $VER <= perl 5.6). As pfaut also pointed out it's not always the best-option, anyways. The standards for threading aren't altogether clear, either, so I'd rather not use it as a production option for code that will be sent out. Therefore, I treat it much like an experimental function that's pretty far along in its development scale. (somewhere between lvalue and the builtins like open() I've come to trust) As you say "As demos, they are probably fine, but for real applications, this is extremely harmful, and makes absolutely no sense."

    However, I prefer to use Net::Server with preforking when I need to create a server to do things. The module deals with a lot of the problems people will have (buffer overlflows, etc.) and is easily extensible. However, as the author asserts, it isn't as popular as the other server implementations (boohooo :O( ), and therefore needs users to write extensions and people to use it. I hope you, as well as other socket server people's try it; I've found it to be a great resource. (It might be interesting to write Net::Server::Threading, since threading is becomming more standardized as time goes on. Just make sure to use 5.8; in your code.)

    I say give threading more time (maybe the next major realease of perl 5 and they'll hopefully be more usable in perl 6). Meanwhile IO::Select and fork() seem to provide viable production alternatives.

    Gyan Kapur
    gkapur@myrealbox.com
      Yes, need to give it more time, but at the same time, should try it out, so more useful info can be feedback to the development.

      Other than the cost of resource, if you ask me to pick one major problem, and only one. I would say that the biggest problem, according to my intensive trial with perl threading, is that bless is not implemented for threading.

      Considering that lots of Perl modules are implemented as object, the bless problem simply made it impossible for you to share things among threads (of course you can share "prime" data types like scalar, array, hash etc.)

      The problem with bless stops me from lots of experiments. As a supporter of perl threading, I hope they can resolve those major problems very soon.
        do you have any more information/links on this bless issue?


        time was, I could move my arms like a bird and...