PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Столкнулся возможно с глюком потока ?


Столкнулся возможно с глюком потока ?

Сообщений 1 страница 6 из 6

1

Собственно пример с этого форума:

Код:
Enumeration 
  #Window_0 
  #Start
  #Text 
EndEnumeration 

Procedure Progr(*x)
  For a=0 To 100000
  SetGadgetText(#Text,Str(a))
  Delay(100)
  Debug "Жив1"
 Next    
EndProcedure  
  
    
OpenWindow(#Window_0, 100, 150, 400, 200, "Работа в потоке",#PB_Window_SystemMenu|#PB_Window_WindowCentered) 
 ButtonGadget(#Start,20,50,70,20,"Старт")   
 TextGadget(#Text, 150,50, 30,20,"")

  Repeat 
    Event = WaitWindowEvent() 
    If Event = #PB_Event_Gadget    
      Select EventGadget() 
        Case #Start  

              If IsThread(ThreadID)=0
               ThreadID=CreateThread(@Progr(), x)
             Else
               Delay (2000)
               MessageRequester("", "Программа занята!", #MB_OK|#MB_ICONWARNING)
              EndIf  

      EndSelect 
    EndIf               
  Until Event = #PB_Event_CloseWindow


Суть - при повторном нажатии Старт поток встает пока не пройдет Delay.
Затык в SetGadgetText.
Как быть ?

Отредактировано Alexsvc (24.03.2017 14:31:09)

0

2

Это особенность винды. SetGadgetText под виндой использует функцию SendMessage предусматривающую гарантированную доставку сообщения (или функция вернет код ошибки если ей это не удастся). Сообщения доставляются при вызове WaitWindowEvent(), по одному сообщению на вызов. Задержка в основном цикле программы - не самое лучшее решение, поскольку в это время "виснут" окна программы и если задержка слишком большая, то винда сообщит что программа не отвечает.

0

3

Спасибо за ответ.
А есть возможность кроме WaitWindowEvent() передать управление во внешние потоки ?
Ситуация в том, что требуется внешние потоки поставить на паузу, но только в том месте где они (потоки) не обращаются к общим данным. Если этого не сделать наступает коллизия данных.
При обработке главного потока  они виснут и  "подождать" из невыходит. Долбить  WaitWindowEvent() - потеря разных эвентов и сильный тормоз интерфейса.
Выходит что выход только в том чтобы  изолировать вывод в интерфейс  в отдельный поток с изоляцией его данных ?

0

4

Вышел из положения долблением WindowEvent() до тех пор пока все процессы не лягут в паузу. Хот и теряю эвенты, но зато все работает и достаточно быстро.
Уж и попортило мне нервов эта "особенность" винды. Думаю имеет право занесения этой особенности в хелп.

0

5

Alexsvc написал(а):

Уж и попортило мне нервов эта "особенность" винды.

В винде хоть как-то работает. В Linux такие действия приводят в вылету программы - GTK не поддерживает многопоточность.

Можно сделать по другому (несколько усложнив программу). Вместо выполнения SetGadgetText в потоке, нужно сгенерировать событие функцией PostEvent и в основном потоке (в котором создано окно) обрабатывать его.

Код:
Enumeration 
  #Window_0 
  #Start
  #Text 
EndEnumeration 

Enumeration #PB_Event_FirstCustomValue
  #Event
EndEnumeration

Procedure Progr(*x)
  For a=0 To 100000
    PostEvent(#Event, #Window_0, #Text, 0, a)
    Delay(100)
    Debug "Жив1"
  Next    
EndProcedure  


OpenWindow(#Window_0, 100, 150, 400, 200, "Работа в потоке",#PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
ButtonGadget(#Start,20,50,70,20,"Старт")   
TextGadget(#Text, 150,50, 30,20,"")

Repeat 
  Event = WaitWindowEvent() 
  If Event = #PB_Event_Gadget    
    Select EventGadget() 
      Case #Start  
        
        If IsThread(ThreadID)=0
          ThreadID=CreateThread(@Progr(), x)
        Else
          Delay (2000)
          MessageRequester("", "Программа занята!", #MB_OK|#MB_ICONWARNING)
        EndIf  
        
    EndSelect 
    
  ElseIf Event = #Event
    SetGadgetText(EventGadget(),Str(EventData()))
  EndIf               
Until Event = #PB_Event_CloseWindow

0

6

Еще раз благодарю за помощь!
:cool:

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Столкнулся возможно с глюком потока ?