亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標題: [Perl]GUI顯示多線程任務(wù)進度 [打印本頁]

作者: 523066680    時間: 2023-04-22 13:20
標題: [Perl]GUI顯示多線程任務(wù)進度
本帖最后由 523066680 于 2023-04-22 13:24 編輯

環(huán)境:Win10, Strawberry Perl

經(jīng)常遇到需要多線程處理的需求,但是在終端混合輸出的結(jié)果非常混亂,即使每條信息加上線程ID,又或是使用不同的縮進。
最初考慮在線程間共享GUI句柄,結(jié)果發(fā)現(xiàn)僅有的幾個GUI框架并不支持線程共享。
    于是改了方案,單獨開一個線程跑GUI,創(chuàng)建一個線程共享的字符串數(shù)組,存儲日志。
    通過 open $H, ">", \$str 的方式為字符串變量創(chuàng)建輸出流句柄,然后 select $H 取代STDOUT輸出。
    在GUI的文本顯示模塊中動態(tài)更新字符串內(nèi)容,目的達成。




  1. # Code By 523066680
  2. use utf8;
  3. use Modern::Perl;
  4. use Encode;
  5. use threads;
  6. use threads::shared;
  7. use Time::HiRes qw/sleep time/;
  8. use IUP ':all';

  9. STDOUT->autoflush(1);
  10. my $th_count = 8;

  11. # 不同線程的日志緩存
  12. my @log :shared;
  13. @log = map { utf8("線程 $_ \n") } ( 0 .. $th_count );  # 0 占位

  14. my @ths;
  15. # 創(chuàng)建線程
  16. grep { push @ths, threads->create( \&th_func, $_ ) } ( 1 .. $th_count );
  17. push @ths, threads->create( \&GUI, 4 );

  18. # 等待運行結(jié)束
  19. while ( threads->list(threads::running) ) { sleep 0.2 };

  20. # 線程分離/結(jié)束
  21. grep { $_->detach() } threads->list(threads::all);

  22. sub th_func
  23. {
  24.     my ( $id ) = @_;

  25.     $SIG{'KILL'} = sub { threads->exit(); };

  26.     # printf "%d %s\n", $id, $log[$id];
  27.     open my $FH, ">>:utf8", \$log[$id];
  28.     select $FH;

  29.     my $n = 1;
  30.     while ( 1 )
  31.     {
  32.         printf "線程 %d -> %03d\n", $id, $n++;
  33.         sleep 0.2;
  34.     }
  35. }

  36. sub GUI
  37. {
  38.     our @edit;
  39.     for my $n ( 1 .. $th_count )
  40.     {
  41.         push @edit, IUP::Text->new(
  42.             FONT => "Simsun, 10",
  43.             MULTILINE => "YES",
  44.             BORDER    => "YES",
  45.             SCROLLBAR => "VERTICAL",
  46.             EXPAND=>"YES",
  47.             BGCOLOR => "#000000",
  48.             FGCOLOR => "#FFFFFF",
  49.             VALUE => "",
  50.         );
  51.     }

  52.     my $box1 = IUP::Vbox->new(
  53.         TABTITLE => "1~4",
  54.         child => [
  55.             IUP::Hbox->new(
  56.                 child => [ $edit[0], $edit[1] ],
  57.                 GAP    => 5,
  58.                 MARGIN => "5x5"
  59.             ),
  60.             IUP::Hbox->new(
  61.                 child => [ $edit[2], $edit[3] ],
  62.                 GAP    => 5,
  63.                 MARGIN => "5x5"
  64.             ),
  65.         ],
  66.         EXPAND => 1,
  67.         GAP    => 5,
  68.         MARGIN => "5x5"
  69.     );

  70.     my $box2 = IUP::Vbox->new(
  71.         TABTITLE => "5~8",
  72.         child => [
  73.             IUP::Hbox->new(
  74.                 child => [ $edit[4], $edit[5] ],
  75.                 GAP    => 5,
  76.                 MARGIN => "5x5"
  77.             ),
  78.             IUP::Hbox->new(
  79.                 child => [ $edit[6], $edit[7] ],
  80.                 GAP    => 5,
  81.                 MARGIN => "5x5"
  82.             ),
  83.         ],
  84.         EXPAND => 1,
  85.         GAP    => 5,
  86.         MARGIN => "5x5"
  87.     );

  88.     my $tabs = IUP::Tabs->new( child => [$box1, $box2 ], TABTYPE=>"TOP",
  89.         PADDING => "10x10",
  90.         FONTSIZE => "12",
  91.         T**RIENTATION => "HORIZONTAL",
  92.     );

  93.     my $dlg = IUP::Dialog->new(
  94.         child => $tabs,
  95.         TITLE => "Console",
  96.         SIZE  => "450x250",
  97.     );

  98.     IUP::Timer->new(ACTION_CB => msg_update->( \[url=home.php?mod=space&uid=31104]@edit[/url] ), TIME => 200, RUN=>'YES');
  99.     $dlg->ShowXY( IUP_CENTER, IUP_CENTER );

  100.     IUP->MainLoop;

  101.     # 如果GUI線程結(jié)束
  102.     for (  threads->list(threads::all) )
  103.     {
  104.         if ( $_->tid() != threads->tid() )
  105.         {
  106.             $_->kill("KILL")->detach();
  107.             printf "detach %d\n", $_->tid();
  108.         }
  109.     }
  110. }

  111. # 日志更新顯示
  112. sub msg_update
  113. {
  114.     my ( $edit ) = @_;
  115.     # 記錄每個ID日志的offset,只打印增量的部分
  116.     # 解決滾動條反彈到頂部的問題 - 如果每次都使用 $obj->VALUE 打印整個日志的話
  117.     my @offset = map {0} ( 0 .. $th_count );

  118.     return sub
  119.     {
  120.         for my $id ( 1 .. $th_count )
  121.         {
  122.             my $len = length( $log[$id] );
  123.             if ( $offset[$id] == 0 )
  124.             {
  125.                 $log[$id] =~ s/\n$//;
  126.                 $edit->[$id-1]->APPEND( $log[$id], 0 );
  127.                 $offset[$id] = $len - 1; # 去掉一個換行符
  128.             }
  129.             elsif ( $len > $offset[$id] )
  130.             {
  131.                 my $str = substr( $log[$id], $offset[$id] );
  132.                 $str=~s/\n$//;
  133.                 $edit->[$id-1]->APPEND( $str );
  134.                 $offset[$id] = $len;
  135.             }

  136.             #$edit->[$id-1]->VALUE( $log[$id] );
  137.         }

  138.         return IUP_DEFAULT;
  139.     };
  140. }

  141. sub gbk { encode('gbk', $_[0]) }
  142. sub utf8 { encode('utf8', $_[0]) }
  143. sub u2gbk { encode('gbk', decode('utf8', $_[0])) }
  144. sub uni { decode('utf8', $_[0]) }
復(fù)制代碼




作者: 523066680    時間: 2023-04-22 13:21
標題: [Perl]GUI顯示多線程任務(wù)進度
本帖最后由 523066680 于 2023-04-22 13:27 編輯

發(fā)重了,清除內(nèi)容
論壇使用上是有些問題了,時代也變了,少人用論壇

GUI顯示多線程日志輸出.gif (673.04 KB, 下載次數(shù): 84)

GUI顯示多線程日志輸出.gif

作者: b114213903    時間: 2023-05-31 14:37
用Win32::GUI,再用不同的線程更新不同的標簽(Label)不是更好看?
作者: 523066680    時間: 2023-06-06 22:02
本帖最后由 523066680 于 2023-06-06 22:03 編輯

回復(fù) 3# b114213903

你是對的




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2