Iczer Posted September 24, 2015 Posted September 24, 2015 I need to synchronise 3 different scripts to work with one object - to make sure only one script is "active". I wanted to use Semaphores for that, but...How i can move from $bGlobalBusyFlag to Semaphores in :expandcollapse popup#include <WinAPI.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 623, 367, 192, 132) $Group1 = GUICtrlCreateGroup("Group1", 8, 8, 185, 105) $Label1 = GUICtrlCreateLabel("Label1", 24, 40, 141, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group2 = GUICtrlCreateGroup("Group2", 8, 128, 185, 105) $Label2 = GUICtrlCreateLabel("Label2", 24, 160, 45, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group3 = GUICtrlCreateGroup("Group3", 8, 248, 185, 105) $Label3 = GUICtrlCreateLabel("Label3", 24, 280, 45, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group4 = GUICtrlCreateGroup("joint output", 232, 8, 377, 345) $Edit1 = GUICtrlCreateEdit("", 248, 32, 345, 305) GUICtrlSetData(-1, "Edit1") GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $bGlobalBusyFlag = False GUICtrlSetBkColor($Group2, 0xffff00) GUICtrlSetBkColor($Group3, 0xffff00) AdlibRegister("Program_1",200) AdlibRegister("Program_2",250) AdlibRegister("Program_3",300) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd AdlibUnRegister("Program_1") AdlibUnRegister("Program_2") AdlibUnRegister("Program_3") Exit Func Program_1() Local Static $t Local Static $tBusyTime, $tFreeTime Local Static $bBusyFlag = False, $bFreeFlag = False, $bWaitFlag = True If $bBusyFlag Then If TimerDiff($t) > $tBusyTime Then $bGlobalBusyFlag = False $bBusyFlag = False $bFreeFlag = True Else GUICtrlSetBkColor($Group1, 0xff0000) ; Red EndIf EndIf If $bWaitFlag Then If $bGlobalBusyFlag Then GUICtrlSetBkColor($Group1, 0xffff00) ; Yellow Else $bGlobalBusyFlag = True $bWaitFlag = False $bBusyFlag = True $tBusyTime = Random(888,3333,1) $tFreeTime = Random(3333,5555,1) $t = TimerInit() EndIf EndIf If $bFreeFlag Then If TimerDiff($t) > $tFreeTime Then $bWaitFlag = True $bFreeFlag = False Else GUICtrlSetBkColor($Group1, 0x00ff00) ; Green EndIf EndIf EndFunc Func Program_2() Local Static $t Local Static $tBusyTime, $tFreeTime Local Static $bBusyFlag = False, $bFreeFlag = False, $bWaitFlag = True If $bBusyFlag Then If TimerDiff($t) > $tBusyTime Then $bGlobalBusyFlag = False $bBusyFlag = False $bFreeFlag = True Else GUICtrlSetBkColor($Group2, 0xff0000) ; Red EndIf EndIf If $bWaitFlag Then If $bGlobalBusyFlag Then GUICtrlSetBkColor($Group2, 0xffff00) ; Yellow Else $bGlobalBusyFlag = True $bWaitFlag = False $bBusyFlag = True $tBusyTime = Random(888,3333,1) $tFreeTime = Random(3333,5555,1) $t = TimerInit() EndIf EndIf If $bFreeFlag Then If TimerDiff($t) > $tFreeTime Then $bWaitFlag = True $bFreeFlag = False Else GUICtrlSetBkColor($Group2, 0x00ff00) ; Green EndIf EndIf EndFunc Func Program_3() Local Static $t Local Static $tBusyTime, $tFreeTime Local Static $bBusyFlag = False, $bFreeFlag = False, $bWaitFlag = True If $bBusyFlag Then If TimerDiff($t) > $tBusyTime Then $bGlobalBusyFlag = False $bBusyFlag = False $bFreeFlag = True Else GUICtrlSetBkColor($Group3, 0xff0000) ; Red EndIf EndIf If $bWaitFlag Then If $bGlobalBusyFlag Then GUICtrlSetBkColor($Group3, 0xffff00) ; Yellow Else $bGlobalBusyFlag = True $bWaitFlag = False $bBusyFlag = True $tBusyTime = Random(888,3333,1) $tFreeTime = Random(3333,5555,1) $t = TimerInit() EndIf EndIf If $bFreeFlag Then If TimerDiff($t) > $tFreeTime Then $bWaitFlag = True $bFreeFlag = False Else GUICtrlSetBkColor($Group3, 0x00ff00) ; Green EndIf EndIf EndFunc"active" - red, waiting - yellow, free - green
jguinch Posted September 24, 2015 Posted September 24, 2015 you say 3 different scripts, but it seems to be 3 different functions, no ?What is the goal ? Ca you describe what your script is supposed to do ? Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
Iczer Posted September 25, 2015 Author Posted September 25, 2015 3 function instead 3 standalone compiled scripts - for simplicity. idea - is to make script(s)/functions use $bBusyFlag (Red) only one at time - while $bGlobalBusyFlag = False
jguinch Posted September 25, 2015 Posted September 25, 2015 My question was : what are the 3 functions supposed to do ? In which order the groups must be colored ? Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
Iczer Posted September 25, 2015 Author Posted September 25, 2015 Those 3 functions only for colouring, nothing more. No special order for colouring.Rules are simple:if $bGlobalBusyFlag = False - work/busy (red) and set$bGlobalBusyFlag = True -after some random time - set $bGlobalBusyFlag = False and colour green -after some random time - going waiting mode (Yellow) and check $bGlobalBusyFlagif $bGlobalBusyFlag = True - waiting (Yellow)repeat
Iczer Posted September 25, 2015 Author Posted September 25, 2015 Could someone rewrite functions : Semaphore_GetState(), Semaphore_SetFree() and Semaphore_SetBusy() to work with Semaphores/Events instead of global variable? expandcollapse popup#include <WinAPI.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 623, 367, 192, 132) $Group1 = GUICtrlCreateGroup("Group1", 8, 8, 185, 105) $Label1 = GUICtrlCreateLabel("Label1", 24, 40, 141, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group2 = GUICtrlCreateGroup("Group2", 8, 128, 185, 105) $Label2 = GUICtrlCreateLabel("Label2", 24, 160, 45, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group3 = GUICtrlCreateGroup("Group3", 8, 248, 185, 105) $Label3 = GUICtrlCreateLabel("Label3", 24, 280, 45, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group4 = GUICtrlCreateGroup("joint output", 232, 8, 377, 345) $Edit1 = GUICtrlCreateEdit("", 248, 32, 345, 305) GUICtrlSetData(-1, "Edit1") GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $bGlobalBusyFlag = False Global $hSemaphore = _WinAPI_CreateSemaphore("Semaphore_Test", 1, 1) Global $g_tEvents = DllStructCreate("handle Event[1];") $g_tEvents.Event(1) = _WinAPI_CreateEvent(0, True, False) GUICtrlSetBkColor($Group2, 0xffff00) GUICtrlSetBkColor($Group3, 0xffff00) AdlibRegister("Program_1",200) AdlibRegister("Program_2",250) AdlibRegister("Program_3",300) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd AdlibUnRegister("Program_1") AdlibUnRegister("Program_2") AdlibUnRegister("Program_3") _WinAPI_CloseHandle($hSemaphore) _WinAPI_CloseHandle($g_tEvents.Event(1)) Exit ;============================================================== Func Program_1() Local Static $t Local Static $tBusyTime, $tFreeTime Local Static $bBusyFlag = False, $bFreeFlag = False, $bWaitFlag = True If $bBusyFlag Then If TimerDiff($t) > $tBusyTime Then Semaphore_SetFree() $bBusyFlag = False $bFreeFlag = True Else GUICtrlSetBkColor($Group1, 0xff0000) ; Red EndIf EndIf If $bWaitFlag Then If Semaphore_GetState() Then GUICtrlSetBkColor($Group1, 0xffff00) ; Yellow Else Semaphore_SetBusy() $bWaitFlag = False $bBusyFlag = True $tBusyTime = Random(888,3333,1) $tFreeTime = Random(3333,5555,1) $t = TimerInit() EndIf EndIf If $bFreeFlag Then If TimerDiff($t) > $tFreeTime Then $bWaitFlag = True $bFreeFlag = False Else GUICtrlSetBkColor($Group1, 0x00ff00) ; Green EndIf EndIf EndFunc ;============================================================== Func Program_2() Local Static $t Local Static $tBusyTime, $tFreeTime Local Static $bBusyFlag = False, $bFreeFlag = False, $bWaitFlag = True If $bBusyFlag Then If TimerDiff($t) > $tBusyTime Then Semaphore_SetFree() $bBusyFlag = False $bFreeFlag = True Else GUICtrlSetBkColor($Group2, 0xff0000) ; Red EndIf EndIf If $bWaitFlag Then If Semaphore_GetState() Then GUICtrlSetBkColor($Group2, 0xffff00) ; Yellow Else Semaphore_SetBusy() $bWaitFlag = False $bBusyFlag = True $tBusyTime = Random(888,3333,1) $tFreeTime = Random(3333,5555,1) $t = TimerInit() EndIf EndIf If $bFreeFlag Then If TimerDiff($t) > $tFreeTime Then $bWaitFlag = True $bFreeFlag = False Else GUICtrlSetBkColor($Group2, 0x00ff00) ; Green EndIf EndIf EndFunc ;============================================================== Func Program_3() Local Static $t Local Static $tBusyTime, $tFreeTime Local Static $bBusyFlag = False, $bFreeFlag = False, $bWaitFlag = True If $bBusyFlag Then If TimerDiff($t) > $tBusyTime Then Semaphore_SetFree() $bBusyFlag = False $bFreeFlag = True Else GUICtrlSetBkColor($Group3, 0xff0000) ; Red EndIf EndIf If $bWaitFlag Then If Semaphore_GetState() Then GUICtrlSetBkColor($Group3, 0xffff00) ; Yellow Else Semaphore_SetBusy() $bWaitFlag = False $bBusyFlag = True $tBusyTime = Random(888,3333,1) $tFreeTime = Random(3333,5555,1) $t = TimerInit() EndIf EndIf If $bFreeFlag Then If TimerDiff($t) > $tFreeTime Then $bWaitFlag = True $bFreeFlag = False Else GUICtrlSetBkColor($Group3, 0x00ff00) ; Green EndIf EndIf EndFunc ;============================================================== Func Semaphore_GetState() ;If Not (_WinAPI_WaitForSingleObject( $g_tEvents.Event(1),0) = -1) Then Return True Return $bGlobalBusyFlag EndFunc ;============================================================== Func Semaphore_SetFree() ;_WinAPI_SetEvent ( $g_tEvents.Event(1) ) $bGlobalBusyFlag = False EndFunc ;============================================================== Func Semaphore_SetBusy() ;_WinAPI_ResetEvent ( $g_tEvents.Event(1) ) $bGlobalBusyFlag = True EndFunc ;==============================================================
Iczer Posted October 7, 2015 Author Posted October 7, 2015 Semaphores still bother me - need help with Semaphore_GetState(), Semaphore_SetFree() and Semaphore_SetBusy() functions.
MilesAhead Posted October 7, 2015 Posted October 7, 2015 Have you considered mutex? it is simpler+1. If you only need to guarantee one routine will write the variable at a time you only need a mutex. A semaphore would be more appropriate to a reference counting situation. In C based languages for protecting a single global integer variable I used InterlockedIncrement and InterlockedDecrement which could be used to set it to 0 or 1 as a boolean flag. My Freeware Page
computergroove Posted October 7, 2015 Posted October 7, 2015 (edited) You could write text to a file and have each script check the number currently in the file and act if its the scripts turn. You could also run a seperate fourth script to control the use of the other 3 scripts. Why not just use 1 script? Edited October 7, 2015 by computergroove Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html
Iczer Posted October 9, 2015 Author Posted October 9, 2015 Indeed, with mutex its simpler (see working example), but for more complex cases than binary-like flag i wanted to understand Semaphores... expandcollapse popup#include <WinAPIProc.au3> #include <GUIConstantsEx.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Mutex Test", 201, 367, (@DesktopWidth-201)/2, (@DesktopHeight-367)/2) $Group1 = GUICtrlCreateGroup("Group1", 8, 8, 185, 105) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group2 = GUICtrlCreateGroup("Group2", 8, 128, 185, 105) GUICtrlCreateGroup("", -99, -99, 1, 1) $Group3 = GUICtrlCreateGroup("Group3", 8, 248, 185, 105) GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $sMutex = "GlobalBusyFlag" Global $hMutex = _WinAPI_CreateMutex($sMutex, False, 0) FileCopy(@ScriptDir&"\Program.exe",@ScriptDir&"\1_Program.exe",1) FileCopy(@ScriptDir&"\Program.exe",@ScriptDir&"\2_Program.exe",1) FileCopy(@ScriptDir&"\Program.exe",@ScriptDir&"\3_Program.exe",1) Run(@ScriptDir&"\1_Program.exe") Run(@ScriptDir&"\2_Program.exe") Run(@ScriptDir&"\3_Program.exe") While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ProcessClose("1_Program.exe") ProcessClose("2_Program.exe") ProcessClose("3_Program.exe") Sleep(333) FileDelete(@ScriptDir&"\1_Program.exe") FileDelete(@ScriptDir&"\2_Program.exe") FileDelete(@ScriptDir&"\3_Program.exe") ExitLoop EndSwitch WEnd #include <WinAPIProc.au3> #include <WinAPI.au3> While 1 Sleep(Random(3333,5555)) Program() WEnd ;============================================================== Func Program() Local $sMutex = "GlobalBusyFlag", $ctrlID Local $sNameNum = Number(StringMid(@ScriptName,1,1)) Switch $sNameNum Case 1 $ctrlID = "[CLASS:Button; INSTANCE:1]" Case 2 $ctrlID = "[CLASS:Button; INSTANCE:3]" Case 3 $ctrlID = "[CLASS:Button; INSTANCE:5]" EndSwitch ControlSetText("[TITLE:Mutex Test]", "", $ctrlID, $sNameNum & " Waiting", 1) Local $hMutex = _WinAPI_OpenMutex($sMutex) _WinAPI_WaitForSingleObject($hMutex) ControlSetText("[TITLE:Mutex Test]", "", $ctrlID, $sNameNum & " Busy", 1) Sleep(Random(3333,5555)) _WinAPI_ReleaseMutex($hMutex) ControlSetText("[TITLE:Mutex Test]", "", $ctrlID, $sNameNum & " Free", 1) EndFunc ;==============================================================
kylomas Posted October 10, 2015 Posted October 10, 2015 Iczer,Semaphores are used to share an object amoung a defined number of threads. Thebasic principle is to decrement the count when a thread uses the object and increment the count when a thread releases tge object. See https://msdn.microsoft.com/en-us/library/windows/desktop/ms685129(v=vs.85).aspx for additional info.Kylomas Forum Rules Procedure for posting code "I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals." - Sir Winston Churchill
LarsJ Posted October 10, 2015 Posted October 10, 2015 kylomas, True. But the threads can belong to different processes.Iczer, Here is a simple example that demonstrates how to use semaphores. The semaphores ensures that only three windows are open at a time. The scripts must be compiled.Parent.au3:#include <WinAPIProc.au3> #include <WinAPI.au3> If Not @Compiled Then MsgBox($MB_SYSTEMMODAL, '', 'To run this script, you must first compile it and then run the (.exe) file.') Exit EndIf Local $hSemaphore = _WinAPI_CreateSemaphore('MySemaphore', 3, 3) For $i = 1 To 10 _WinAPI_WaitForSingleObject($hSemaphore) ShellExecute( "Child.exe", $i ) Next _WinAPI_CloseHandle($hSemaphore)Child.au3:#include <WinAPIProc.au3> #include <GUIConstantsEx.au3> $hGui = GUICreate( "Child #" & $CmdLine[1], 250, 200 ) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd _WinAPI_ReleaseSemaphore( _WinAPI_OpenSemaphore( 'MySemaphore' ) ) Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions
MilesAhead Posted October 10, 2015 Posted October 10, 2015 (edited) Years ago I wrote a Max Instance component for Delphi using semaphores. Where it can get tricky is if the first or master instance that creates the semaphore is closed while some of the secondary instances are still open. If the Master instance destroys the semaphore on close then a new instance can create the semaphore again and you could end up with more than the max number of instances intended.It has been many years since I messed with it. So I don't recall the best solution to that issue. Anyway, it is something to keep in mind when planning the interaction controls of the threads. Edited October 10, 2015 by MilesAhead My Freeware Page
willichan Posted November 20, 2015 Posted November 20, 2015 You might try modifying my UDF for your purposes. My UDFs: Barcode Libraries, Automate creation of any type of project folder, File Locking with Cooperative Semaphores, Inline binary files, Continue script after reboot, WinWaitMulti, Name Aggregator, Enigma, CornedBeef Hash
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now