免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3185 | 回复: 6
打印 上一主题 下一主题

通道阻塞,使用了多线程也无用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-22 11:55 |只看该作者 |倒序浏览
5可用积分
http://bbs.chinaunix.net/thread-1272762-1-1.html
5分求助!

问二的继续:http://bbs.chinaunix.net/thread-1270279-1-1.html

按stop可以暂停了,但是图形界面显然通道阻塞了(不可控)使用了多线程也无用。继续请教各位高手!

use Win32::GUI qw();
use threads;

#create main window
my $main = Win32::GUI::Window->new(
    -name   => 'Main',
    -width  => 410,
    -height => 220,
    -text   => 'test',
         -maxsize => [410, 220],
  -minsize => [410, 220],
);

$Text_Informa=$main->AddTextfield(
    -name => "Text_Informa",
    -left => 10,
    -top  => 80,
    -width => 383,
    -height => 100,
    -multiline => 1,
);


$main->AddButton(-name => 'btnDown', -text => 'Download',-left => 265, -top => 45,);
$btnStop=$main->AddButton(-name => 'btnStop', -text => 'Stop',-left => 338, -top => 45,);


# initialization
my $w = $main->ScaleWidth();
my $h = $main->ScaleHeight();
my $desk = Win32::GUI::GetDesktopWindow();
my $dw = Win32::GUI::Width($desk);
my $dh = Win32::GUI::Height($desk);
my $x = ($dw - $w) / 2;
my $y = ($dh - $h) / 2;
$main->Move($x, $y);
$main->Show();

Win32::GUI:ialog();  
exit(0);

# window event handler
sub Main_Terminate {
    -1; #terminate the message loop
}

sub Main_Resize {
    $main->Resize($main->ScaleWidth - 20, $main->ScaleHeight - 40);
}   



sub btnDown_Click {
        my $thr = new threads(\&mythread );
        $thr->detach();
}



sub mythread {
$pg = 9;
while($pg > 1){
$Text_Informa->Append( "$pg\n";
sleep 1;
if($control==1){last;}
$pg--;
}}

sub EndIt {my  $con=shift; <>; $$con=1; return;  }   
#参考自[http://topic.csdn.net/t/20050503/16/3981999.html#[/url]
sub btnStop_Click { my $thr1 = new threads(\&mythread1); $thr1->join(); }
sub mythread1 {my $thd=new threads("EndIt",\$control); $thd->join(); }

[ 本帖最后由 3chi01 于 2008-9-22 11:57 编辑 ]

最佳答案

查看完整内容

帮你改了改你的代码。自己参考一下吧。[ 本帖最后由 Rob 于 2008-9-24 19:52 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-09-22 11:55 |只看该作者


  1. use strict;
  2. use threads 1.39;
  3. use threads::shared;
  4. use Thread::Queue;
  5. use Win32::GUI ();

  6. # 最大线程数
  7. my $Max :shared = 2;
  8. # 退出程序标记
  9. my $Quit :shared = 0;
  10. # 线程开始标记
  11. my $Start :shared = 0;
  12. # 线程退出标记
  13. my $Stop :shared = 0;
  14. # 创建一个队列,线程间数据交换
  15. my $q = Thread::Queue->new();
  16. # 预建一个线程,用于线程管理
  17. threads->create('waiter')->detach;

  18. # GUI事件循环内不要放耗费CPU时间的操作
  19. # 可以考虑将GUI会话单独放入一个线程
  20. #create main window
  21. my $main = Win32::GUI::Window->new(
  22.         -name   => 'Main',
  23.         -width  => 410,
  24.         -height => 220,
  25.         -text   => 'test',
  26.         -maxsize => [410, 220],
  27.         -minsize => [410, 220],
  28. );

  29. $main->AddTextfield(
  30.         -name => "Text_Informa",
  31.         -left => 10,
  32.         -top  => 80,
  33.         -width => 383,
  34.         -height => 100,
  35.         -multiline => 1,
  36. );

  37. $main->AddButton(-name => 'btnDown', -text => 'Download',-left => 265, -top => 45,);
  38. $main->AddButton(-name => 'btnStop', -text => 'Stop',-left => 338, -top => 45,);

  39. # initialization
  40. my $w = $main->ScaleWidth();
  41. my $h = $main->ScaleHeight();
  42. my $desk = Win32::GUI::GetDesktopWindow();
  43. my $dw = Win32::GUI::Width($desk);
  44. my $dh = Win32::GUI::Height($desk);
  45. my $x = ($dw - $w) / 2;
  46. my $y = ($dh - $h) / 2;
  47. $main->Move($x, $y);
  48. $main->Show();
  49. $main->AddTimer('T1', 100);

  50. Win32::GUI::Dialog();  
  51. exit(0);

  52. sub waiter
  53. {
  54.         while (!$Quit) {
  55.                 for (my $num = $Max - threads->list(); $num && $Start; $num--) {
  56.                         threads->create('mythread');
  57.                 }
  58.                 sleep 1;
  59.         }
  60. }

  61. sub mythread {
  62.         my $pg = 9;
  63.         while($pg > 1){
  64.                 $q->enqueue($pg);
  65.                 sleep 1;
  66.                 if($Stop == 1){last;}
  67.                 $pg--;
  68.         }
  69.     threads->detach();
  70.     threads->exit();
  71. }

  72. # window event handler
  73. sub Main_Terminate {
  74.         $main->Hide();
  75.         $Quit = $Stop = 0;
  76.         sleep 1;
  77.     -1; #terminate the message loop
  78. }

  79. sub Main_Resize {
  80.     $main->Resize($main->ScaleWidth - 20, $main->ScaleHeight - 40);
  81. }   

  82. sub btnDown_Click {
  83.         #my $thr = new threads(\&mythread );
  84.         #$thr->detach();
  85.         $Start = 1;
  86.         $Stop = 0;
  87. }

  88. sub btnStop_Click {
  89.         $Stop = 1;
  90.         $Start = 0;
  91. }

  92. sub T1_Timer
  93. {
  94.         return unless $q->pending();
  95.         my $p = $q->dequeue_nb();
  96.         $main->{Text_Informa}->Append($p . "\n");
  97. }

  98. #sub EndIt {my  $con=shift; <>; $$con=1; return; }   
  99. #参考自[[url]http://topic.csdn.net/t/20050503/16/3981999.html#[/url][/url]
  100. #sub mythread1 {my $thd=new threads("EndIt",\$control); $thd->join(); }

复制代码



帮你改了改你的代码。
自己参考一下吧。

[ 本帖最后由 Rob 于 2008-9-24 19:52 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-09-22 14:51 |只看该作者
显然问题出在你用了“<>”, STDIN操作是一个I/O阻塞,在Win32下你不输入ENTER是没办法终止的,
*nix下你可以能过alarm+SIG去终止,但Win32下不可行。
不明白,既然你用了Win32-GUI,为何还需要控制台输入? 仅仅为了测试?为何不在GUI中控件中获取输入?

如果一定要这样要,可以试试用Win32-Console
或者TermReadKey

论坛徽章:
0
4 [报告]
发表于 2008-09-22 17:47 |只看该作者
原帖由 Rob 于 2008-9-22 14:51 发表
显然问题出在你用了“”, STDIN操作是一个I/O阻塞,在Win32下你不输入ENTER是没办法终止的,
*nix下你可以能过alarm+SIG去终止,但Win32下不可行。
不明白,既然你用了Win32-GUI,为何还需要控制台输入? 仅 ...


多谢rob指点,学到好多知识。如何改下面的这句,请给一些意见,万分感谢!
sub EndIt {my  $con=shift; <>; $$con=1; return;  }   


我尝试去掉<>,还是一样的阻塞呀!
sub EndIt { return;  }   

[ 本帖最后由 3chi01 于 2008-9-22 18:05 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-09-22 18:14 |只看该作者
是不是别的地方还有大毛病,搞不懂了。

[ 本帖最后由 3chi01 于 2008-9-22 18:18 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2008-09-24 23:32 |只看该作者
多谢rob大侠,辛苦。万分感激中,我要好好消化一下了!

帮了我大忙。

论坛徽章:
0
7 [报告]
发表于 2009-02-10 09:17 |只看该作者
用rob大侠的代码很好用,但为什么刚开始每个数字出现两次呢,继续运行好像才会一次?
谢谢哪位老师解答。
  1. use strict;
  2. use threads 1.39;
  3. use threads::shared;
  4. use Thread::Queue;
  5. use Win32::GUI ();

  6. # 最大线程数
  7. my $Max :shared = 2;
  8. # 退出程序标记
  9. my $Quit :shared = 0;
  10. # 线程开始标记
  11. my $Start :shared = 0;
  12. # 线程退出标记
  13. my $Stop :shared = 0;
  14. # 创建一个队列,线程间数据交换
  15. my $q = Thread::Queue->new();
  16. # 预建一个线程,用于线程管理
  17. threads->create('waiter')->detach;

  18. # GUI事件循环内不要放耗费CPU时间的操作
  19. # 可以考虑将GUI会话单独放入一个线程
  20. #create main window
  21. my $main = Win32::GUI::Window->new(
  22.         -name   => 'Main',
  23.         -width  => 410,
  24.         -height => 220,
  25.         -text   => 'test',
  26.         -maxsize => [410, 220],
  27.         -minsize => [410, 220],
  28. );

  29. $main->AddTextfield(
  30.         -name => "Text_Informa",
  31.         -left => 10,
  32.         -top  => 80,
  33.         -width => 383,
  34.         -height => 100,
  35.         -multiline => 1,
  36. );

  37. $main->AddButton(-name => 'btnDown', -text => 'Download',-left => 265, -top => 45,);
  38. $main->AddButton(-name => 'btnStop', -text => 'Stop',-left => 338, -top => 45,);

  39. # initialization
  40. my $w = $main->ScaleWidth();
  41. my $h = $main->ScaleHeight();
  42. my $desk = Win32::GUI::GetDesktopWindow();
  43. my $dw = Win32::GUI::Width($desk);
  44. my $dh = Win32::GUI::Height($desk);
  45. my $x = ($dw - $w) / 2;
  46. my $y = ($dh - $h) / 2;
  47. $main->Move($x, $y);
  48. $main->Show();
  49. $main->AddTimer('T1', 100);

  50. Win32::GUI::Dialog();  
  51. exit(0);

  52. sub waiter
  53. {
  54.         while (!$Quit) {
  55.                 for (my $num = $Max - threads->list(); $num && $Start; $num--) {
  56.                         threads->create('mythread');
  57.                 }
  58.                 sleep 1;
  59.         }
  60. }

  61. sub mythread {
  62.         my $pg = 9;
  63.         while($pg > 1){
  64.                 $q->enqueue($pg);
  65.                 sleep 1;
  66.                 if($Stop == 1){last;}
  67.                 $pg--;
  68.         }
  69.     threads->detach();
  70.     threads->exit();
  71. }

  72. # window event handler
  73. sub Main_Terminate {
  74.         $main->Hide();
  75.         $Quit = $Stop = 0;
  76.         sleep 1;
  77.     -1; #terminate the message loop
  78. }

  79. sub Main_Resize {
  80.     $main->Resize($main->ScaleWidth - 20, $main->ScaleHeight - 40);
  81. }   

  82. sub btnDown_Click {
  83.         #my $thr = new threads(\&mythread );
  84.         #$thr->detach();
  85.         $Start = 1;
  86.         $Stop = 0;
  87. }

  88. sub btnStop_Click {
  89.         $Stop = 1;
  90.         $Start = 0;
  91. }

  92. sub T1_Timer
  93. {
  94.         return unless $q->pending();
  95.         my $p = $q->dequeue_nb();
  96.         $main->{Text_Informa}->Append($p . "\n");
  97. }

  98. #sub EndIt {my  $con=shift; <>; $$con=1; return; }   
  99. #参考自[[url]http://topic.csdn.net/t/20050503/16/3981999.html#[/url][/url]
  100. #sub mythread1 {my $thd=new threads("EndIt",\$control); $thd->join(); }
复制代码

[ 本帖最后由 3chi01 于 2009-2-10 09:18 编辑 ]

a5.jpg (38.28 KB, 下载次数: 36)

a5.jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP