Announcement

Collapse
No announcement yet.

CreateEvent with multiple instances

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • CreateEvent with multiple instances

    Found solution. SLEEP at least 20-milliseconds before each shell.

    Is a new event created for each application or is it system wide?

    If I shell to the same program in a loop, multiple applications will hang.

    https://docs.microsoft.com/en-us/win...i-createeventa

    Code:
     typ.hEventReady = CreateEvent (BYVAL 0, BYVAL %TRUE, BYVAL %FALSE, BYVAL 0)
     THREAD CREATE MyThread(VARPTR(typ)) TO hThread(x)  '1) handle is in array
     waitforsingleobject typ.hEventReady,%INFINITE
     CloseHandle typ.hEventReady

    Using Michael Mattias method to CreateEvent eliminates the need to SLEEP after thread create.
    That can dramatically reduce the amount of time.
    Just found out that running the application multiple times will hang some of the multiple instances.
    Code:
    %UseEvents=999 'REM  this line to not use CreateEvent
    %UseSleep=0    'dramatically slows down thread creation so using CreateEvent
    #INCLUDE "win32api.inc"
    
    TYPE MyType
      ThreadNumber AS LONG
      hEventReady AS LONG
    END TYPE
    GLOBAL gsTest             AS STRING   'MID$(gsTest,Threadnumber) = "Z"
    GLOBAL glsleepinthread    AS LONG     'sleep before finish in each thread
    FUNCTION PBMAIN AS LONG               'allocation.bas
     LOCAL x,tests,threads,testnum AS LONG
     LOCAL StartTime,EndTime       AS SINGLE
    
     tests   = 10                          'test this many times
     threads = 200                        'threads per test
     glsleepinthread = 50                 'sleep ms in each thread before finish
     StartTime = TIMER
     #IF %DEF(%UseEvents)                 'only needed with CreateEvent
     LOCAL typ     AS MyType
     #ENDIF
    
     FOR testnum = 1 TO tests
      gsTest = SPACE$(threads)
      REDIM hthread(1 TO threads) AS LONG
    
    
      FOR x= 1 TO threads
    
       #IF %DEF(%UseEvents)
        typ.ThreadNumber = x
        typ.hEventReady = CreateEvent (BYVAL 0, BYVAL %TRUE, BYVAL %FALSE, BYVAL 0)
        THREAD CREATE MyThread(VARPTR(typ)) TO hThread(x)  '1) handle is in array
        IF %UseSleep THEN SLEEP 1
        waitforsingleobject typ.hEventReady,%INFINITE
        REM waitforsingleobject hThread(x),%INFINITE       '2) do not wait here
        CloseHandle typ.hEventReady
       #ELSE
        THREAD CREATE MyThread(x) TO hThread(x)
        IF %UseSleep THEN SLEEP 1
       #ENDIF
    
      NEXT x
    
      ThreadWait hThread()
      FOR x = 1 TO threads
       THREAD CLOSE hThread(x) TO hThread(x)
      NEXT
      IF TALLY(gsTest,"Z") <> threads THEN ? USING$("Only # threads marked Z",TALLY(gsTest,"Z")),%MB_SYSTEMMODAL:EXIT FOR
     NEXT TestNum
     EndTime = TIMER
     BEEP
    REM #IF 0
     #IF %DEF(%UseEvents)
     ? USING$("# tests creating # threads (#-ms wait in each thread)",tests,threads,glsleepinthread),%MB_SYSTEMMODAL,_
       USING$("YES Events Complete in #.# seconds",EndTime-StartTime)
     #ELSE
       ? USING$("# tests creating # threads (#-ms wait in each thread)",tests,threads,glsleepinthread),%MB_SYSTEMMODAL,_
       USING$("NO Events Complete in #.# seconds",EndTime-StartTime)
     #ENDIF
    REM #ENDIF
    
    END FUNCTION
    
    FUNCTION ThreadWait(hThread() AS LONG) AS LONG
     LOCAL ret,StartIndex,ThreadRemain,CurrentGroup,maxthread AS LONG
     maxthread = ARRAYATTR(hThread(),4)  'waitformultiplethreads.bas 11/13/21
     StartIndex   = 1
     ThreadRemain = MaxThread
     DO
      CurrentGroup = MIN(%MAXIMUM_WAIT_OBJECTS, ThreadRemain)
      ret = WaitForMultipleObjects(CurrentGroup,BYVAL VARPTR(hThread(StartIndex)),%TRUE,%INFINITE)
      StartIndex   = StartIndex   + %MAXIMUM_WAIT_OBJECTS
      ThreadRemain = ThreadRemain - %MAXIMUM_WAIT_OBJECTS
     LOOP WHILE ThreadRemain > 0
    END FUNCTION
    
    #IF %DEF(%UseEvents)
    THREAD FUNCTION MyThread(BYVAL p AS MyType PTR) AS LONG
      LOCAL t AS MyType
      t = @p
      SetEvent t.hEventReady
      MID$(gsTest,t.Threadnumber) = "Z"
      SLEEP glSleepInThread 'prevent thread from finishing for a bit
    END FUNCTION
    #ELSE
    THREAD FUNCTION MyThread(BYVAL ThreadNumber AS LONG) AS LONG
    MID$(gsTest,Threadnumber) = "Z"
    SLEEP glSleepInThread 'prevent thread from finishing
    END FUNCTION
    #ENDIF'

  • #2
    Is a new event created for each application or is it system wide?
    Events are system objects.

    From the WinAPI docL

    Remarks The OpenEvent function enables multiple processes to open handles of the same event object. The function succeeds only if some process has already created the event by using the CreateEvent function.
    Source: https://docs.microsoft.com/en-us/sea...crosoft%20Edge


    You may also use the DuplicateHandle() function if you have an unnamed event you wish to use in another process. REF: https://docs.microsoft.com/en-us/win...uplicatehandle

    Where you will also note..
    DuplicateHandle can be used to duplicate a handle between a 32-bit process and a 64-bit process. The resulting handle is appropriately sized to work in the target process. For more information, see Process Interoperability.

    If I shell to the same program in a loop, multiple applications will hang.
    Failing code not shown. It should not have anything to do with the use of events per se. Are you sure you did not code a deadlock somewhere?



    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      If you don't see an error,please don't waste time checking this extreme test.
      Thanks, Michael.

      I don't plan on starting the same program this quickly.
      This might be starving the operating system having time to allocate resources.

      Failing code is above. Compiled as "allocation.exe"
      The code below was written to see if it would run many times. It does fail.

      Using SLEEP 1 in the above application prevents the hangs
      or
      SLEEP 20 in the below program prevents the hangs without needing SLEEP 1 in the above program.
      The purpose was to get rid of SLEEP and CreateEvent does it.
      Code:
      FUNCTION PBMAIN AS LONG
       FOR x& = 1 TO 30
        pid??? = SHELL("allocation.exe")  'thread program above using CreateEvent
        'SLEEP 20
       NEXT
      END FUNCTION

      Comment


      • #4
        The code below was written to see if it would run many times. It does fail.
        Then don't do that.

        You ARE trying to create six thousand threads of execution (30 SHELLs of 200 THREAD CREATEs). Is that too many under Win/32?
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          MM you are right.
          About 1965 Windows 10 32-bit and 1575 Windows 10 64-bit.
          Sleep was not the problem.
          https://techcommunity.microsoft.com/...ds/ba-p/723824

          Comment

          Working...
          X