[Perl] Новичкам: задаем вопросы

Discussion in 'PHP' started by _Great_, 26 May 2007.

Thread Status:
Not open for further replies.
  1. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Чуток только регулярку подправить
    Code:
    ... \s*(.*?)(\d*)\n|\Z/gm
    
     
  2. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    вопрос, есть такой код:
    Code:
    #!/usr/bin/perl
    use threads;
    use threads::shared;
    my $n : shared;
    
    $a = gets();
    print $a . "\n";
    
    sub gets {
       $thr = 10;
       $n = 0; 
       for(0..$thr) {
           $trl[$_] = threads->create(\&gets1);
       }
       for(0..$thr) {
           $trl[$_]->join;
       }
       sub gets1 {
          $| = 1;
          $ii = "";
          while ($n < 10) {
                { lock($n);
                $n++; }
                $ii .= $n; 
                print $ii . "\n";
          }
          return $ii;
       }
    }   
    
    как получить значение $ii ?

    Т.е. как бы примеров с многопоточными функции в инете полно, но везде производится просто ВЫВОД НА МОНИТОР, как именно ВЕРНУТЬ полученное значение, чтобы использовать его дальше? Спасибо
     
    #1222 Pashkela, 25 Oct 2009
    Last edited: 25 Oct 2009
  3. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Code:
    $res = $trl[$_]->join;
    
     
    1 person likes this.
  4. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    спасибо, задумка понятна, но там join в цикле, при попыке ретурна обрываются потоки, как корректно прилепить этот вариант к коду выше?
     
  5. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    а что предполагается получить?
     
  6. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
  7. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Я в более глобальном смысле)
     
  8. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    То значение, которое выводится на экран, мне надо не прости вывести на экран, но получит возможность работать с этой переменной дальше. Как еще объяснить - хз.
     
  9. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    если переписать функцию gets1 так
    Code:
    sub gets1 {
      $| = 1;
      $ii = "";
      $i = 0;
      while ($n < 10) {
        { lock($n);
        $n++; }
        $ii .= $n;
        #print $ii . "\n";
        $i++;
      }
      print $i, "\n";
    }
    
    получим вывод
    Code:
    10
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    
    Цикл while отрабатывает лишь в первом потоке. Переменная $ii определена после цикла лишь при первом вызове подпрограммы. Это так и предполагается?)
     
    #1229 krypt3r, 25 Oct 2009
    Last edited: 25 Oct 2009
  10. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    издеваешься?:) Еще раз:

     
  11. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Ну почему же издеваюсь. Если воткнуть print $ii не перед закрывающей фигурной сккобкой, а после (перед ретурном), все будет видно)

    ЗЫ.
    Code:
    #!/usr/bin/perl
    use threads;
    use threads::shared;
    my $n : shared;
    
    $a = gets();
    print $_, "\n" for @$a;
    #print $a . "\n";
    
    sub gets {
      $thr = 10;
      $n = 0;
      for(0..$thr) {
        $trl[$_] = threads->create(\&gets1);
      }
      for(0..$thr) {
        $res[$_] = $trl[$_]->join;
      }
      sub gets1 {
        $| = 1;
        $ii = "";
        while ($n < 10) {
          { lock($n);
          $n++; }
          $ii .= $n;
          #print $ii . "\n";
        }
        #print $ii, "\n";
        return $ii;
      }
      return \@res;
    }
    
     
  12. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    круть, спасибо, если заменить на

    print $_, "\r" for @$a;

    то как раз то, что надо

    PS: Но остался последний момент, это опять вывод просто на экран, а если $ii мне нужно как число для дальнейших операций, то вариант не подходит

    Т.е. вопрос в том, как мне выцепить после всех этих извращенств число "12345678910" и юзать его дальше
     
    #1232 Pashkela, 25 Oct 2009
    Last edited: 25 Oct 2009
  13. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Ну вот, к примеру, надо добавить к коду каждого символа строки число 2 и вывести на экран новую строку
    Code:
    $a = gets();
    @b = unpack 'C*', $a->[0];
    $_ += 2 for @b;
    print pack 'C*', @b;
    
     
    #1233 krypt3r, 25 Oct 2009
    Last edited: 25 Oct 2009
  14. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    спасибо, твои советы мне очень помогли
     
  15. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    Еще вопрос, с получением и дальнейшей обработкой данных из потоков разобрался. Но, если в потоке идет не простейшая локальная математическая операция, но получение данных из интернета посредством сокетов например, то нарушается очередность записи данных в массив. Т.е. что-то парсится раньше и пишется не свою очередь. Получается, что данные как бы все есть, но разрозненные. Вопрос - как заставить писать данные в массив в порядке заданной очереди, а не в порядке времени физического получения ответа? Спасибо

    PS: Перечитал весь топик, серьезно, похожая проблема была у .Slip, но с точностью до наоборот - у меня тут афигенная асинхронность, но нарушается очередь записи, а надо по порядку. Надеюсь на вас, античатовцы :)
     
    #1235 Pashkela, 26 Oct 2009
    Last edited: 26 Oct 2009
  16. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Юзать хэш и затем отсортировать его по ключам
     
  17. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    это-то понятно, выше мы рассмотрели пример ретурна числа, и возвращали через массив, а как сделать ретурн хеша из multithread функции без предварительных его записывания в массив-посредник? Чтобы вернуть чистый хеш с ключами с результатами работы всех потоков, помеченными ключиками и, соотвественно, легко разбирающимися. Спасибо.
     
    #1237 Pashkela, 26 Oct 2009
    Last edited: 26 Oct 2009
  18. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Заполняем хэш и делаем в конце функции
    Code:
    return \%myhash;
    
     
  19. Pashkela

    Pashkela Динозавр

    Joined:
    10 Jan 2008
    Messages:
    2,750
    Likes Received:
    1,044
    Reputations:
    339
    Code:
    #!/usr/bin/perl
    use threads;
    use threads::shared;
    my $n : shared;
    
    $a = gets();
    print $_, "\n" for @$a;
    #print $a . "\n";
    
    sub gets {
      $thr = 10;
      $n = 0;
      for(0..$thr) {
        $trl[$_] = threads->create(\&gets1);
      }
      for(0..$thr) {
        $res[$_] = $trl[$_]->join;
      }
      sub gets1 {
        $| = 1;
        $ii = "";
        while ($n < 10) {
          { lock($n);
          $n++; }
          $ii .= $n;
          $hash{$n} = $ii;
          #print $ii . "\n";
        }
        #print $ii, "\n";
        return \%hash
      }
      return \@res;
    }
    
    Относительно кода выше - как вернуть хеш, не так же ведь. И надо ли его шарить в мультитреде. Т.е. нужно, чтобы ключи у хеша были именно как в коде выше = $n. Только так потом можно будет идентифицировать данные
     
    #1239 Pashkela, 26 Oct 2009
    Last edited: 26 Oct 2009
  20. krypt3r

    krypt3r Elder - Старейшина

    Joined:
    27 Apr 2007
    Messages:
    1,507
    Likes Received:
    389
    Reputations:
    101
    Ну если юзать расшаренный хэш, то
    Code:
    #!/usr/bin/perl                 
    use threads;                    
    use threads::shared;            
    my $n : shared;                 
    my %hash : shared = ();         
    #my $refhash : shared = \%hash; 
    
    $a = gets();
    print $_, ' => ', $hash{$_}, "\n" for keys %hash;
    
    sub gets {
      $thr = 10;
      $n = 0;
      %res = ();
      for(0..$thr) {
        $trl[$_] = threads->create(\&gets1);
      }
      for(0..$thr) {
        $trl[$_]->join;
      }
      sub gets1 {
        $| = 1;
        $ii = "";
        while ($n < 10) {
          { lock($n);
          $n++; }
          $ii .= $n;
          $hash{$n} = $ii;
        }
      }
    }
    
    
     
Thread Status:
Not open for further replies.