Re: Accept / Connect will block using threads and UNIX domain sockets
[email protected] (Sebastian Weber) Mon, 29 Jan 2007 18:51:19 +0100
| Newsgroups | perl.ithreads |
|---|---|
| Message-ID | <[email protected]> |
Thanks a lot for the help. I tested around a little bit and found, that
just using "require Socket;import Socket ':all';" instead of "use
Socket;" solves the problem.
That means, the below code will work OK and will not block:
#!/usr/bin/perl
use threads;
#use Socket; <- this would block !!
require Socket;
import Socket ':all';
unlink ("/tmp/mysock");
my $t=threads->create("con_thread");
socket (SOCK1,PF_UNIX,SOCK_STREAM,0) or die "socket(): $!";
bind (SOCK1, sockaddr_un("/tmp/mysock")) or die "bind(): $!";
listen(SOCK1,SOMAXCONN) or die "listen(): $!";
accept (CLIENT,SOCK1);
$t->join();
sub con_thread {
sleep(2);
socket(SOCK2, PF_UNIX, SOCK_STREAM, 0) or die "socket(): $!";
connect(SOCK2, sockaddr_un("/tmp/mysock")) or die "connect(): $!";
}
This is very strange as I always thought "use" and "require, import" are
equivalents ...
Jerry D. Hedden wrote:
> Sebastian Weber wrote:
>
>> The following code sets up a UNIX domain socket server
>> and connects to that server in a different thread. I found the
>> following
>> code using threads to block forever - ist blocks exactly at the
>> connect
>> / accept calls:
>>
>> #!/usr/bin/perl
>> use threads;
>> use Socket;
>>
>> unlink ("/tmp/mysock");
>> $t=threads->create("con_thread");
>>
>> socket (SOCK1,PF_UNIX,SOCK_STREAM,0) or die "socket(): $!";
>> bind (SOCK1, sockaddr_un("/tmp/mysock")) or die "bind(): $!";
>> listen(SOCK1,SOMAXCONN) or die "listen(): $!";
>> accept (CLIENT,SOCK1);
>> $t->join();
>>
>> sub con_thread {
>> sleep(2);
>> socket(SOCK2, PF_UNIX, SOCK_STREAM, 0) or die "socket(): $!";
>> connect(SOCK2, sockaddr_un("/tmp/mysock")) or die "connect():
>> $!";
>> }
>>
>> Whereas the same code will not block using fork():
>>
>> #!/usr/bin/perl
>> use threads;
>> use Socket;
>>
>> unlink ("/tmp/mysock");
>> if (fork) {con_thread();exit;}
>>
>> socket (SOCK1,PF_UNIX,SOCK_STREAM,0) or die "socket(): $!";
>> bind (SOCK1, sockaddr_un("/tmp/mysock")) or die "bind(): $!";
>> listen(SOCK1,SOMAXCONN) or die "listen(): $!";
>> accept (CLIENT,SOCK1);
>>
>> sub con_thread {
>> sleep(2);
>> socket(SOCK2, PF_UNIX, SOCK_STREAM, 0) or die "socket(): $!";
>> connect(SOCK2, sockaddr_un("/tmp/mysock")) or die "connect():
>> $!";
>> }
>>
>> Does anybody have any idea why?? Is there a workaround?
>> BTW: Im using Perl v5.8.7 built for cygwin-thread-multi-64int
>>
>
> The problem is that Socket is not thread-safe. You can work around
> this by loading Socket into the main thread after creating the child
> thread, and loading it separately in the child thread:
>
> #!/usr/bin/perl
>
> use threads;
>
> unlink ("/tmp/mysock");
> my $t=threads->create("con_thread");
>
> require Socket;
> import Socket ':all';
>
> socket (SOCK1,PF_UNIX,SOCK_STREAM,0) or die "socket(): $!";
> bind (SOCK1, sockaddr_un("/tmp/mysock")) or die "bind(): $!";
> listen(SOCK1,SOMAXCONN) or die "listen(): $!";
> accept (CLIENT,SOCK1);
>
> $t->join();
>
> sub con_thread {
> require Socket;
> import Socket ':all';
>
> sleep(2);
> socket(SOCK2, PF_UNIX, SOCK_STREAM, 0) or die "socket(): $!";
> connect(SOCK2, sockaddr_un("/tmp/mysock")) or die "connect(): $!";
> }
>
___________________________________________________________
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de