使用GtkAda进行Ada线程切换

时间:2015-07-02 05:18:59

标签: multithreading gtk ada

我创建的任务似乎没有放弃控制,因此主线程将运行。我不知道为什么。由于这是我第一次尝试在Ada中使用多线程(在GNAT下使用GtkAda),我确信我在这里缺少一些基本原则。

我的主要看起来像这样:

procedure Main is
begin
   Test_Gui.Gui_Task.Gui_Initialize;
   Test_Gui.Simple_Switch_Test;
   Msg("Done");
end;

在包Test_Gui中,规范和正文代码如下所示:

task type Gui_Type is
  entry Gui_Initialize;
  entry Gui_Reset_SwitCh_To_1;
  entry Gui_Display_Message(Message : String);
  entry Gui_Write_Debug;
end Gui_Type;

Gui_Task : Gui_Type;

task body Gui_Type is
begin
   loop
      select
         accept Gui_Initialize  do
            Initialize;
         end Gui_Initialize;
      or
          accept Gui_Reset_Switch_To_1  do
            Reset_Switch_To_1;
         end Gui_Reset_Switch_To_1;
      or
         accept Gui_Display_Message (Message : in String) do
            Display_Message(Message);
         end Gui_Display_Message;
      or
         accept Gui_Write_Debug  do
            Debug_Label.Set_Label(Debug_Label_Text);               
         end Gui_Write_Debug;
      else
         Gdk.Threads.Enter;
         Dead := Gtk.Main.Main_Iteration;
         Gdk.Threads.Leave;
        delay 0.01;
     end select;
  end loop;
end Gui_Type;

从main调用的第二个方法Simple_Switch_Test,它调用Redisplay_Item_And_Get_Switches中对GUI任务的调用。

procedure Simple_Switch_Test is

  Text  : String(1..80) := (others => ' ');
  Msg   : String(1..16);

begin
  loop
     Count := Count + 1;
     Copy_String(Integer'Image(Count), Text);
     for I in 1..16 loop
        Msg(I) := Text(I);
     end loop;

     Redisplay_Item_And_Get_Switches(Msg);

     Copy_String("some stuff.."), Debug_Label_Text );

     Gui_Task.Gui_Write_Debug;

     delay 0.01;

  end loop;

end;

初始化工作和GUI功能,即使其回调工作。但是,在第一次从Simple_Switch_Test调用Redisplay_Item_And_Get_Switches后,将代码放入GUI任务循环中,除了处理回调之外,它永远不会留下else子句。

因此,它永远不会调用Gui_Task.Gui_Write_Debug并在主任务中继续该代码。

我已在调试器中验证过这一点。

我认为每个循环中的延迟会暂停相关任务,但我显然不能正确理解它。此代码是否可以修复而无需太多更改? (我希望我得到正确的任务基本框架。)它缺少什么或错了?

1 个答案:

答案 0 :(得分:3)

我看到的问题是,Gtkada位于非Ada产品Gtk之上,不支持Ada的任务模型。

根据Dmitry Kazakov's "GTKAda Contributions" library

  

GTK +被认为是不安全的任务。特别是,所有调用都需要从同一个任务(线程)进行。

我没有比在该链接上阅读他的文档更好的建议,特别是第一节“1.使用GTK +进行任务”,其中包含1.1节中的示例,并且 - 如果您觉得它有用 - 下载并使用他的支持库

(如果人们认为这应该是评论,我会这样做)