Linux - Thread und GTK

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Linux - Thread und GTK

Beitrag von mk-soft »

Bei meinen ersten geh versuche in Linux ich habe festgestellt das die GTK etwas empfindlich gestört wird wenn man versucht aus einen Thread Gadgets zu bearbeiten.

Habe das ganze mal umgangen mit einen kleinen Message-System :allright:

Testcode:

Code: Alles auswählen


EnableExplicit

;- Konstanten
Enumeration ; Window ID
  #Window
EndEnumeration

Enumeration ; Menu ID
  #Menu
EndEnumeration

Enumeration ; MenuItem ID
  #Menu_Exit
EndEnumeration

Enumeration ; Statusbar ID
  #Statusbar
EndEnumeration

Enumeration ; Gadget ID
  #List
EndEnumeration

; ***************************************************************************************

Procedure UpdateWindow()

  Protected x,y,dx,dy
  Protected mn,st,tb
  
  x = 0
  y = 0
  mn = MenuHeight()
  st = StatusBarHeight(#StatusBar)
  ;tb = ToolBarHeight(#ToolBar)
  dx = WindowWidth(#Window)
  dy = WindowHeight(#Window) - mn - st - tb
  ResizeGadget(#List, x, y, dx, dy)
  
EndProcedure

;- Globale Variablen
Global exit = 0

IncludeFile "message.pb"

Define.l style, event, window, menu, type

Declare MyThread(id)

;- Fenster
style = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 400, 300, "Fenster", style)
  ; Menu
  If CreateMenu(#Menu, WindowID(#Window))
    MenuTitle("&Datei")
      MenuItem(#Menu_Exit, "Be&enden")
  EndIf
  ; Statusbar
  CreateStatusBar(#Statusbar, WindowID(#Window))
    AddStatusBarField(1024)
  ; Gadgets
  If CreateGadgetList(WindowID(#Window))
    ListViewGadget(#List, 0,0,0,0)
  EndIf
  
  UpdateWindow()
  
  CreateThread(@MyThread(), 1)
  
  ;-- Hauptschleife
  Repeat
    event   = WaitWindowEvent(20)
    window  = EventWindow()
    menu    = EventMenu()
    type    = EventType()
    
    ; Messages abarbeiten
    GetMessage()
    
    Select event
      Case #PB_Event_Menu
        Select menu
          Case #Menu_Exit
            Exit = 1
        EndSelect
      Case #PB_Event_Gadget
      Case #PB_Event_CloseWindow
        Exit = 1
      Case #PB_Event_Repaint
      Case #PB_Event_SizeWindow
        UpdateWindow()
        
      Case #PB_Event_MoveWindow
      Case #PB_Event_ActivateWindow
      Case #PB_Event_SysTray
    
    EndSelect
    
  Until Exit
EndIf


; ***************************************************************************************

Procedure MyThread(id)

  PutMessage(#List, #additemtext, 0, "Thread startet...")
  Delay(500)
  While exit = 0
    PutMessage(#List, #additemtext, 0, "Thread läuft...")
    Delay(1000)
  Wend
  
EndProcedure
; ***************************************************************************************
Includecode "message.pb":

Code: Alles auswählen

;-TOP
; Kommentar     : 
; Author        : mk-soft
; Second Author : 
; Datei         : message.pb
; Version       : 1.01
; Erstellt      : 25.07.2007
; Geändert      :
; 
; Compilermode  :
;
; ***************************************************************************************

;- Messages
Enumeration 100
  #settext
  #additemtext
  #insertitemtext
EndEnumeration

; ***************************************************************************************

Structure udtMessage
  id.l
  msg.l
  value.l
  text.s
EndStructure

Global NewList ListMessage.udtMessage()
Global MutexMessage

MutexMessage = CreateMutex()

; ***************************************************************************************

Procedure PutMessage(id.l, msg.l, value.l = 0, text.s = "")

  LockMutex(MutexMessage)
  AddElement(ListMessage())
  With ListMessage()
    \id = id
    \msg = msg
    \value = value
    \text = text
  EndWith
  UnlockMutex(MutexMessage)
  
EndProcedure

; ***************************************************************************************

Procedure GetMessage()
  
  LockMutex(MutexMessage)
  ForEach ListMessage()
    With ListMessage()
      ; Messages ToDo
      Select \msg
        Case #settext
          SetGadgetText(\id, \text)        
        Case #additemtext
          AddGadgetItem(\id, -1, \text)
        Case #insertitemtext
          AddGadgetItem(\id, \value, \text)
      EndSelect
    EndWith
  Next
  ClearList(ListMessage())
  UnlockMutex(MutexMessage)
  
EndProcedure
FF :wink:

(EDIT) Geht natürlich auch unter Windows
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Beitrag von Blackskyliner »

Da ich Linux Nutzer bin und ich finde, dass es einfach nur fantastisch ist, was du da gemacht hast, hab ich mal ein bisschen geupdated und (hoffentlich) alle verändernden Funktionen eingebaut.

Das kann man sicherlich auch noch einfacher gestalten, wenn jemand wüsste wie wäre das nett es zu Posten :)

Code: Alles auswählen

;-TOP
; Name 	    : Thread-Safe Gadget Management (TSGM)
; Kommentar     :
; Author        : mk-soft
; Second Author : Blackskyliner
; Datei         : message.pb
; Version       : 1.2
; Erstellt      : 25.07.2007
; Geändert      : 31.01.2008
;
; Compilermode  :
;
; ***************************************************************************************

;- Messages
Enumeration 100
	#TSGM_AddGadgetColumn
	#TSGM_AddGadgetItem
	#TSGM_ChangeListIconGadgetDisplay
	#TSGM_ClearGadgetItemList
	#TSGM_DisableGadget
	#TSGM_FreeGadget
	#TSGM_GadgetToolTip
	#TSGM_HideGadget
	#TSGM_RemoveGadgetColumn
	#TSGM_RemoveGadgetItem
	#TSGM_ResizeGadget
	
	#TSGM_SetActiveGadget
	#TSGM_SetGadgetAttribute
	#TSGM_SetGadgetColor
	#TSGM_SetGadgetData
	#TSGM_SetGadgetFont
	#TSGM_SetGadgetItemAttribute
	#TSGM_SetGadgetItemColor
	#TSGM_SetGadgetItemData
	#TSGM_SetGadgetItemState
	#TSGM_SetGadgetItemText
	#TSGM_SetGadgetState
	#TSGM_SetGadgetText
EndEnumeration

; ***************************************************************************************

Structure TSGM_MessageStruct
	GadgetID.l
	
	MessageTyp.l
	
	AddGadgetColumn_Position.l
	AddGadgetColumn_Title.s
	AddGadgetColumn_Width.l
	
	AddGadgetItem_Position.l
	AddGadgetItem_Text.s
	AddGadgetItem_ImageID.l
	AddGadgetItem_Flags.l
	
	ChangeListIconGadgetDisplay_Mode.l
	
	DisableGadget_State.l
	
	GadgetToolTip_Text.s
	
	HideGadget_State.l
	
	RemoveGadgetColumn_Column.l
	
	RemoveGadgetItem_Position.l
	
	ResizeGadget_x.l
	ResizeGadget_y.l
	ResizeGadget_Width.l
	ResizeGadget_Height.l
	
	SetGadgetAttribute_Attribute.l
	SetGadgetAttribute_Value.l
	
	SetGadgetColor_ColorType.l
	SetGadgetColor_Color.l
	
	SetGadgetData_Value.l
	
	SetGadgetFont_FontID.l
	
	SetGadgetItemAttribute_Position.l
	SetGadgetItemAttribute_Attribute.l
	SetGadgetItemAttribute_Value.l
	SetGadgetItemAttribute_Column.l
	
	SetGadgetItemColor_Item.l
	SetGadgetItemColor_ColorType.l
	SetGadgetItemColor_Color.l
	SetGadgetItemColor_Column.l

	SetGadgetItemData_Item.l
	SetGadgetItemData_Value.l
	
	SetGadgetItemState_Position.l
	SetGadgetItemState_State.l
	
	SetGadgetItemText_Position.l
	SetGadgetItemText_Text.s
	SetGadgetItemText_Column.l
	
	SetGadgetState_State.l
	
	SetGadgetText_Text.s
EndStructure

Global NewList TSGM_MessageQuenue.TSGM_MessageStruct()
Global TSGM_Mutex_MessageQuenue

TSGM_Mutex_MessageQuenue = CreateMutex()

; ***************************************************************************************

Procedure TSGM_addMessage(GadgetID.l, Message.TSGM_MessageStruct())
	LockMutex(TSGM_Mutex_MessageQuenue)
	AddElement(TSGM_MessageQuenue())
	
	
	TSGM_MessageQuenue()\GadgetID = GadgetID
	
	TSGM_MessageQuenue()\MessageTyp = Message()\MessageTyp
	
	
	TSGM_MessageQuenue()\AddGadgetColumn_Position			= Message()\AddGadgetColumn_Position
	TSGM_MessageQuenue()\AddGadgetColumn_Title			= Message()\AddGadgetColumn_Title
	TSGM_MessageQuenue()\AddGadgetColumn_Width			= Message()\AddGadgetColumn_Width
	TSGM_MessageQuenue()\AddGadgetItem_Position			= Message()\AddGadgetItem_Position
	TSGM_MessageQuenue()\AddGadgetItem_Text				= Message()\AddGadgetItem_Text
	TSGM_MessageQuenue()\AddGadgetItem_ImageID			= Message()\AddGadgetItem_ImageID
	TSGM_MessageQuenue()\AddGadgetItem_Flags				= Message()\AddGadgetItem_Flags
	TSGM_MessageQuenue()\ChangeListIconGadgetDisplay_Mode		= Message()\ChangeListIconGadgetDisplay_Mode
	TSGM_MessageQuenue()\DisableGadget_State				= Message()\DisableGadget_State
	TSGM_MessageQuenue()\GadgetToolTip_Text				= Message()\GadgetToolTip_Text
	TSGM_MessageQuenue()\HideGadget_State				= Message()\HideGadget_State
	TSGM_MessageQuenue()\RemoveGadgetColumn_Column			= Message()\RemoveGadgetColumn_Column
	TSGM_MessageQuenue()\RemoveGadgetItem_Position			= Message()\RemoveGadgetItem_Position
	TSGM_MessageQuenue()\ResizeGadget_x					= Message()\ResizeGadget_x
	TSGM_MessageQuenue()\ResizeGadget_y					= Message()\ResizeGadget_y
	TSGM_MessageQuenue()\ResizeGadget_Width				= Message()\ResizeGadget_Width
	TSGM_MessageQuenue()\ResizeGadget_Height				= Message()\ResizeGadget_Height
	TSGM_MessageQuenue()\SetGadgetAttribute_Attribute		= Message()\SetGadgetAttribute_Attribute
	TSGM_MessageQuenue()\SetGadgetAttribute_Value			= Message()\SetGadgetAttribute_Value
	TSGM_MessageQuenue()\SetGadgetColor_ColorType			= Message()\SetGadgetColor_ColorType
	TSGM_MessageQuenue()\SetGadgetColor_Color				= Message()\SetGadgetColor_Color
	TSGM_MessageQuenue()\SetGadgetData_Value				= Message()\SetGadgetData_Value
	TSGM_MessageQuenue()\SetGadgetFont_FontID				= Message()\SetGadgetFont_FontID
	TSGM_MessageQuenue()\SetGadgetItemAttribute_Position		= Message()\SetGadgetItemAttribute_Position
	TSGM_MessageQuenue()\SetGadgetItemAttribute_Attribute		= Message()\SetGadgetItemAttribute_Attribute
	TSGM_MessageQuenue()\SetGadgetItemAttribute_Value		= Message()\SetGadgetItemAttribute_Value
	TSGM_MessageQuenue()\SetGadgetItemAttribute_Column		= Message()\SetGadgetItemAttribute_Column
	TSGM_MessageQuenue()\SetGadgetItemColor_Item			= Message()\SetGadgetItemColor_Item
	TSGM_MessageQuenue()\SetGadgetItemColor_ColorType		= Message()\SetGadgetItemColor_ColorType
	TSGM_MessageQuenue()\SetGadgetItemColor_Color			= Message()\SetGadgetItemColor_Color
	TSGM_MessageQuenue()\SetGadgetItemColor_Column			= Message()\SetGadgetItemColor_Column
	TSGM_MessageQuenue()\SetGadgetItemData_Item			= Message()\SetGadgetItemData_Item
	TSGM_MessageQuenue()\SetGadgetItemData_Value			= Message()\SetGadgetItemData_Value
	TSGM_MessageQuenue()\SetGadgetItemState_Position		= Message()\SetGadgetItemState_Position
	TSGM_MessageQuenue()\SetGadgetItemState_State			= Message()\SetGadgetItemState_State
	TSGM_MessageQuenue()\SetGadgetItemText_Position			= Message()\SetGadgetItemText_Position
	TSGM_MessageQuenue()\SetGadgetItemText_Text			= Message()\SetGadgetItemText_Text
	TSGM_MessageQuenue()\SetGadgetItemText_Column			= Message()\SetGadgetItemText_Column
	TSGM_MessageQuenue()\SetGadgetState_State				= Message()\SetGadgetState_State
	TSGM_MessageQuenue()\SetGadgetText_Text				= Message()\SetGadgetText_Text

	
	UnlockMutex(TSGM_Mutex_MessageQuenue)
EndProcedure

; ***************************************************************************************

Procedure TSGM_doWork()
	LockMutex(TSGM_Mutex_MessageQuenue)
	
	ForEach TSGM_MessageQuenue()
		With TSGM_MessageQuenue()
			; Messages ToDo
			Select \MessageTyp
 				Case #TSGM_AddGadgetColumn
 					AddGadgetColumn(\GadgetID, \AddGadgetColumn_Position, \AddGadgetColumn_Title, \AddGadgetColumn_Width)
				Case #TSGM_AddGadgetItem
					If \AddGadgetItem_ImageID
						If \AddGadgetItem_Flags
							AddGadgetItem(\GadgetID, \AddGadgetItem_Position,\AddGadgetItem_Text,\AddGadgetItem_ImageID,\AddGadgetItem_Flags)
						Else
							AddGadgetItem(\GadgetID, \AddGadgetItem_Position,\AddGadgetItem_Text,\AddGadgetItem_ImageID)
						EndIf
					Else
						AddGadgetItem(\GadgetID, \AddGadgetItem_Position,\AddGadgetItem_Text)
					EndIf
				Case #TSGM_ChangeListIconGadgetDisplay
					ChangeListIconGadgetDisplay(\GadgetID, \ChangeListIconGadgetDisplay_Mode)
				Case #TSGM_ClearGadgetItemList
					ClearGadgetItemList(\GadgetID)
				Case #TSGM_DisableGadget
					DisableGadget(\GadgetID, \DisableGadget_State)
				Case #TSGM_FreeGadget
					FreeGadget(\GadgetID)
				Case #TSGM_GadgetToolTip
					GadgetToolTip(\GadgetID, \GadgetToolTip_Text)
				Case #TSGM_HideGadget
					HideGadget(\GadgetID, \HideGadget_State)
				Case #TSGM_RemoveGadgetColumn
					RemoveGadgetColumn(\GadgetID, \RemoveGadgetColumn_Column)
				Case #TSGM_RemoveGadgetItem
					RemoveGadgetItem(\GadgetID, \RemoveGadgetItem_Position)
				Case #TSGM_ResizeGadget
					ResizeGadget(\GadgetID, \ResizeGadget_x, \ResizeGadget_y, \ResizeGadget_Width, \ResizeGadget_Height)
				
				Case #TSGM_SetActiveGadget
					SetActiveGadget(\GadgetID)
				Case #TSGM_SetGadgetAttribute
					SetGadgetAttribute(\GadgetID, \SetGadgetAttribute_Attribute, \SetGadgetAttribute_Value)
				Case #TSGM_SetGadgetColor
					SetGadgetColor(\GadgetID, \SetGadgetColor_ColorType, \SetGadgetColor_Color)
				Case #TSGM_SetGadgetData
					SetGadgetData(\GadgetID, \SetGadgetData_Value)
				Case #TSGM_SetGadgetFont
					SetGadgetFont(\GadgetID, \SetGadgetFont_FontID)
				Case #TSGM_SetGadgetItemAttribute
					If \SetGadgetItemAttribute_Column
						SetGadgetItemAttribute(\GadgetID, \SetGadgetItemAttribute_Position, \SetGadgetItemAttribute_Attribute, \SetGadgetItemAttribute_Value, \SetGadgetItemAttribute_Column)
					Else
						SetGadgetItemAttribute(\GadgetID, \SetGadgetItemAttribute_Position, \SetGadgetItemAttribute_Attribute, \SetGadgetItemAttribute_Value)
					EndIf
				Case #TSGM_SetGadgetItemColor
					
					If \SetGadgetItemColor_Column
						SetGadgetItemColor(\GadgetID, \SetGadgetItemColor_Item, \SetGadgetItemColor_ColorType, \SetGadgetItemColor_Color, \SetGadgetItemColor_Column)
					Else
						SetGadgetItemColor(\GadgetID, \SetGadgetItemColor_Item, \SetGadgetItemColor_ColorType, \SetGadgetItemColor_Color)
					EndIf
				Case #TSGM_SetGadgetItemData
					SetGadgetItemData(\GadgetID, \SetGadgetItemData_Item, \SetGadgetItemData_Value)
				Case #TSGM_SetGadgetItemState
					SetGadgetItemState(\GadgetID, \SetGadgetItemState_Position, \SetGadgetItemState_State)
				Case #TSGM_SetGadgetItemText
					If \SetGadgetItemText_Column
						SetGadgetItemText(\GadgetID, \SetGadgetItemText_Position, \SetGadgetItemText_Text, \SetGadgetItemText_Column)
					Else
						SetGadgetItemText(\GadgetID, \SetGadgetItemText_Position, \SetGadgetItemText_Text)
					EndIf
				Case #TSGM_SetGadgetState
					SetGadgetState(\GadgetID, \SetGadgetState_State)
				Case #TSGM_SetGadgetText
					SetGadgetText(\GadgetID, \SetGadgetText_Text)
			EndSelect
		EndWith
	Next
	
	ClearList(TSGM_MessageQuenue())
	UnlockMutex(TSGM_Mutex_MessageQuenue)
EndProcedure 

Code: Alles auswählen

EnableExplicit

;- Konstanten
Enumeration ; Window ID
  #Window
EndEnumeration

Enumeration ; Menu ID
  #Menu
EndEnumeration

Enumeration ; MenuItem ID
  #Menu_Exit
EndEnumeration

Enumeration ; Statusbar ID
  #Statusbar
EndEnumeration

Enumeration ; Gadget ID
  #List
EndEnumeration

; ***************************************************************************************

Procedure UpdateWindow()
	Protected x,y,dx,dy
	Protected mn,st,tb
	
	x = 0
	y = 0
	mn = MenuHeight()
	st = StatusBarHeight(#StatusBar)
	;tb = ToolBarHeight(#ToolBar)
	dx = WindowWidth(#Window)
	dy = WindowHeight(#Window) - mn - st - tb
	ResizeGadget(#List, x, y, dx, dy)
EndProcedure

;- Globale Variablen
Global exit = 0

IncludeFile "message.pb"

Define.l style, event, window, menu, type

Declare MyThread(id)

;- Fenster
style = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 400, 300, "Fenster", style)
	; Menu
	If CreateMenu(#Menu, WindowID(#Window))
		MenuTitle("&Datei")
		MenuItem(#Menu_Exit, "Be&enden")
	EndIf
	; Statusbar
	CreateStatusBar(#Statusbar, WindowID(#Window))
	AddStatusBarField(1024)
	; Gadgets
	If CreateGadgetList(WindowID(#Window))
		ListViewGadget(#List, 0,0,0,0)
	EndIf
	
	UpdateWindow()
	
	CreateThread(@MyThread(), 1)
	
	;-- Hauptschleife
	Repeat
		event   = WaitWindowEvent(20)
		window  = EventWindow()
		menu    = EventMenu()
		type    = EventType()
		
		; Messages abarbeiten
		TSGM_doWork()
		
		Select event
			Case #PB_Event_Menu
				Select menu
					Case #Menu_Exit
						Exit = 1
				EndSelect
			Case #PB_Event_Gadget
			Case #PB_Event_CloseWindow
				Exit = 1
			Case #PB_Event_Repaint
			Case #PB_Event_SizeWindow
				UpdateWindow()
			
			Case #PB_Event_MoveWindow
			Case #PB_Event_ActivateWindow
			Case #PB_Event_SysTray
		EndSelect	
	Until Exit
EndIf


; ***************************************************************************************
Procedure MyThread(id)
	NewList MessageToSend.TSGM_MessageStruct()
	AddElement(MessageToSend())
	
	MessageToSend()\MessageTyp = #TSGM_AddGadgetItem
	MessageToSend()\AddGadgetItem_Position = 0
	MessageToSend()\AddGadgetItem_Text = "Thread startet..."

	TSGM_addMessage(#List, MessageToSend())
	Delay(500)
	While exit = 0
		MessageToSend()\MessageTyp = #TSGM_AddGadgetItem
		MessageToSend()\AddGadgetItem_Position = -1
		MessageToSend()\AddGadgetItem_Text = "Thread läuft..."

		TSGM_addMessage(#List, MessageToSend())
		Delay(1000)
	Wend
 
EndProcedure
; *************************************************************************************** 
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Tolle Sache :allright:

Hat zwar nichts mit Gadgets zu tun, aber ich habe vor einiger Zeit auch mal
ein Thread-Message-System gebastelt. Passt gerade gut hier, deshalb will
ich es euch nicht vorenthalten:

Code: Alles auswählen

Structure __MSGTHREAD
  id.l
  msg.l
  hasMsg.l
EndStructure

Global NewList __msg_threads.__MSGTHREAD()
Global __msg_mutex.l = CreateMutex()

Procedure TMSG_RegisterThread(id.l)
  LockMutex(__msg_mutex)
  AddElement(__msg_threads())
  With __msg_threads()
    \id = id
    \msg = 0
    \hasMsg = #False
  EndWith
  UnlockMutex(__msg_mutex)
EndProcedure

Procedure TMSG_RemoveThread(id.l)
  LockMutex(__msg_mutex)
  ForEach __msg_threads()
    With __msg_threads()
      If \id = id
        DeleteElement(__msg_threads())
        Break
      EndIf
    EndWith
  Next
  UnlockMutex(__msg_mutex)
EndProcedure

Procedure.l TMSG_SendMessage(id.l, msg.l)
  Protected *th.__MSGTHREAD
  
  With __msg_threads()
    LockMutex(__msg_mutex)
    ForEach __msg_threads()
      If \id = id
        *th = @__msg_threads()
        Break
      EndIf
    Next
    UnlockMutex(__msg_mutex)
  EndWith
  
  If *th
    While #True
      LockMutex(__msg_mutex)
      If *th\hasMsg = #False
        Break
      EndIf
      UnlockMutex(__msg_mutex)
      Delay(0)
    Wend
    
    *th\hasMsg = #True
    *th\msg = msg
    UnlockMutex(__msg_mutex)
  EndIf
  
EndProcedure

Procedure.l TMSG_HasMessage(id.l)
  LockMutex(__msg_mutex)
  ForEach __msg_threads()
    If __msg_threads()\id = id
      If __msg_threads()\hasMsg
        UnlockMutex(__msg_mutex)
        ProcedureReturn #True
      Else
        UnlockMutex(__msg_mutex)
        ProcedureReturn #False
      EndIf
    EndIf
  Next
  UnlockMutex(__msg_mutex)
EndProcedure

Procedure.l TMSG_GetMessage(id.l)
  Protected msg.l
  
  LockMutex(__msg_mutex)
  ForEach __msg_threads()
    If __msg_threads()\id = id
      If __msg_threads()\hasMsg
        __msg_threads()\hasMsg = #False
        msg = __msg_threads()\msg
        UnlockMutex(__msg_mutex)
        ProcedureReturn msg
      Else
        UnlockMutex(__msg_mutex)
        ProcedureReturn #False
      EndIf
    EndIf
  Next
  UnlockMutex(__msg_mutex)
EndProcedure


Procedure Thread1(id.l)
  While Not TMSG_HasMessage(id)
    Delay(100)
  Wend
  Debug TMSG_GetMessage(id)
  TMSG_SendMessage(2, 888)
EndProcedure

Procedure Thread2(id.l)
  TMSG_SendMessage(1, 999)
  While Not TMSG_HasMessage(id)
    Delay(100)
  Wend
  Debug TMSG_GetMessage(id)
  TMSG_SendMessage(0, 0)
EndProcedure

TMSG_RegisterThread(0) ; main
TMSG_RegisterThread(1)
TMSG_RegisterThread(2)
CreateThread(@Thread1(), 1)
CreateThread(@Thread2(), 2)


Repeat
  Delay(100)
Until TMSG_HasMessage(0)
Antworten