no threads
TRANSCRIPT
YAPC::Russiano threads;
Что ждут от потоков?
• Лёгкие (память)
• Эффективный обмен данными
• Выполняются параллельно
Что ждут от потоков?
• Лёгкие (память)
• Эффективный обмен данными
• Выполняются параллельно
Что ждут от потоков?
• Лёгкие (память)
• Эффективный обмен данными
• Выполняются параллельно
Что ждут от потоков?
• Лёгкие (память)
• Эффективный обмен данными
• Выполняются параллельно• Потери на синхронизацию
Что ждут от потоков?
• Лёгкие (память)
• Эффективный обмен данными
• Выполняются параллельно• Потери на синхронизацию
• Не требуют изменений в коде?
no Perl?
• PHP
• Python
• C++/Java/C#• Erlang
Run me!
use threads;
binmode(STDOUT, ":encoding(ISO-8859-1)");
threads->create(sub{})->join();
Run me!
use threads;
binmode(STDOUT, ":encoding(ISO-8859-1)");
threads->create(sub{})->join();
segmentation fault ./perltest/threaded-sysmalloc/bin/perl -e
Run me!
use threads;
opendir(DIR, "/");
threads->create(sub{})->join();
Run me!
use threads;
opendir(DIR, "/");
threads->create(sub{})->join();
segmentation fault ./perltest/threaded-sysmalloc/bin/perl -e
use threads;
use Large::Module;
use Another::Large::Module;
sub foo{sleep 10}
threads->create(\&foo) for (1..100);
Run me!
use threads;
use Large::Module;
use Another::Large::Module;
sub foo{sleep 10}
threads->create(\&foo) for (1..100); #oom, wtf???
Run me!
use threads;
use threads::shared;
my $bar :shared;
sub foo {sleep 10}
threads->create(\&foo)->detach() for (1..10);
print BSD::Process->new->rssize;
Run me!
use threads;
use threads::shared;
my $bar :shared;
sub foo {sleep 10}
threads->create(\&foo)->detach() for (1..10);
print BSD::Process->new->rssize; # 3276
Run me!
use threads;
use threads::shared;
my $bar :shared;
$bar = “a”x1_000_000;
sub foo {sleep 10}
threads->create(\&foo)->detach() for (1..10);
print BSD::Process->new->rssize;
Run me!
use threads;
use threads::shared;
my $bar :shared;
$bar = “a”x1_000_000;
sub foo {sleep 10}
threads->create(\&foo)->detach() for (1..10);
print BSD::Process->new->rssize; # 8935
Run me!
use threads;
use threads::shared;
my $bar :shared;
$bar = “a”x1_000_000; # magic inside
sub foo {sleep 10}
threads->create(\&foo)->detach() for (1..10);
print BSD::Process->new->rssize;
Run me!
Для чего используют потоки?
• Устранить «бутылочное горлышко»– Сети– Одного процессора
– Диска
• Уменьшить время отклика системы
use threads;
my (@a, @b);
@a=(0..100_000);
@b=@a;
@a=sort @a;
@b=sort @b;
time ./bin/perl test_nothr.pl
0.19s user 0.02s system 99% cpu 0.208 total
Run me!
use threads;
my (@a, @b);
@a=(0..100_000);
@b=@a;
push @thr,
threads->create(sub{@a=sort@a}),
threads->create(sub{@b=sort@b});
$_->join() for @thr;
time ./bin/perl test_thr.pl
1.18s user 0.15s system 147% cpu 0.898 total
Run me!
use threads;
my @a :shared; my @b :shared;
@a=(0..100_000);
@b=@a;
push @thr,
threads->create(sub{@a=sort@a}),
threads->create(sub{@b=sort@b});
$_->join() for @thr;
time ./bin/perl test_thr.pl
1.31s user 0.15s system 151% cpu 0.960 total
Run me!
use threads;
use JSON::XS;
threads->create(sub {
JSON::XS->new->….;
});
Run me!
use threads;
#use JSON::XS;
no JSON::XS;
Run me!
Чем заменить?
• Сеть– AnyEvent– IO::Lambda– Coro
• Диск– IO::Async– IO::AIO
• Процессор– Gearman– plain old fork
Run me!use AnyEvent; use AnyEvent::HTTP;
sub fetch_next{ my $domain = shift @list;http_request
GET => "http://$domain/favicon.ico", recurse => 0, timeout => 30, cookie_jar => {}, headers => {Referer => "http://$domain/"}, sub { my ($data, $headers) = @_;
if ($headers->{'Status'} == 200){ #process data} fetch_next();
};
}
Не весь CPAN одинаково полезен
package HTTP::Async;use Time::HiRes qw/sleep/;…$self->{poll_interval} = 0.05;sub _next_response {
…sleep $self->{poll_interval};
}
use threads
• GUI
• Win
use threads
• pre-«fork»• no use• no globals
Вопросы?