dcsimg
Results 1 to 15 of 15
  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,638

    VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    This demonstrates, how one can implement robust, asynchronous Workers in VB6 -
    by using a (cross-process) SharedMemory-approach (which is one of the common IPC-mechanisms).

    For convenient usage, the more complex stuff (the MemoryMapping- as well as the CreateProcess-APIs),
    are encapsulated in two generic "Drop-In"-Classes (cIPCMaster and cIPCWorker).

    Those Classes can be used either "split-up" (in separate VB6-Projects for Master and Worker) -
    but also "all-in-one" (when the same Project - or Process - is used to act as Master and Worker both).

    The latter case (using an "all-in-one"-Project), is the most convenient for developing/testing.
    Here the Worker-Process is "shelled" against the same ExeName as the Main- (or Master-) Project,
    using a simple "forking" in Sub Main() ... (as shown below from the content of Demo1 modMain.bas):
    Code:
    Option Explicit
    
    Sub Main() 'Process-Startup-Forking
      If Len(Trim$(Command$)) = 0 Then 'no Cmd-Arg was passed (it was started as the Master-Process)
        fMaster.Show '... so we simply startup the Main-Form
        
      Else 'it was started as a WorkerProcess (pass the CommandLine-Arg into the WorkerRoutine)
        EnterWorkerLoop New cIPCWorker, Trim$(Command$)
      End If
    End Sub
    Above, the blue-colored call represents the "master-fork-path" to your normal "GUI-Project-Code"
    (entered when no Commandline-Param was passed to your Executable).

    And as the magenta-colored routine-name (in the "worker-fork-path") suggests, the upstarting worker is not fired up
    like in an old "classic WebServer-CGI-call" (where the Process exits, after only a single Job was performed).

    Instead the current mechanism is implemented in a way, that the WorkerProcess is fired up once -
    and then enters an "IDLE-loop" (waiting for Jobs, provided by the Master-Process later).
    This way one of the disadvantages of MultiProcessing (the higher Startup-Costs, compared to MultiThreading) is avoided.

    The advantages of doing MultiProcessing instead of threading are:
    - no typelibs, no extra-Dlls are needed
    - in the IDE (after compiling the same Project), the asynchronous workers will behave the same way as in the compiled binary
    - a hard terminate of a worker is possible in a stable and "residue-free" manner (though graceful termination-support is of course built-in)
    - the communication between Master and Worker(s) happens in an absolute "non-blocking" way

    To explain the last point above a bit more... "non-blocking" means, that neither Post- or SendMessage-calls are involved
    (as in VB6-OleBased-Communications between "threaded Apartments", where Events, raised from the Workers will block the Main-Thread) -
    nor are there other mechanisms in play like Mutexes or CriticalSections, which are normally used in conjunction with shared memory...

    Instead the Demo shows, how "state-machine-based" communication (using the shared mem-area) can be implemented.

    The approach is extremely robust, completely IDE- and crash-safe, and "cleans up after itself" under any circumstances:
    - upstarted Worker-Processes will automatically close, when the Master-Class goes out of scope
    - you can even use the IDE-stop-button, whilst asynchronous workers are "deep within a Job" (worker-processes will autoclose nevertheless)

    There is also not a single thing, which is "forbidden to use" in the workers (like in many of the threading-approaches for VB6)...

    The Zip below comes with 3 Demo-Folders (a simple one to get up to speed - and two "medium-difficult" ones for MandelBrot-rendering).

    Ok, here is, what the MandelBrot-Demos will produce (using two Workers, independent from the Main-App):


    And here's the Demo-Zip: IPCSharedMem.zip

    Have fun...

    Olaf

  2. #2
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    555

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Very interesting. I'm sure I can find a use for it. Thanks for sharing.

    J.A. Coutts

  3. #3
    New Member
    Join Date
    Jan 2018
    Posts
    14

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    This looks really useful. I could never get named pipes working for IPC, and TCP is just so much overhead when you only need simple communication between processes.

  4. #4
    Addicted Member
    Join Date
    Aug 2016
    Posts
    242

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by Schmidt View Post
    This demonstrates, how one can implement robust, asynchronous Workers in VB6 -
    by using a (cross-process) SharedMemory-approach (which is one of the common IPC-mechanisms).

    For convenient usage, the more complex stuff (the MemoryMapping- as well as the CreateProcess-APIs),
    are encapsulated in two generic "Drop-In"-Classes (cIPCMaster and cIPCWorker).

    Those Classes can be used either "split-up" (in separate VB6-Projects for Master and Worker) -
    but also "all-in-one" (when the same Project - or Process - is used to act as Master and Worker both).

    The latter case (using an "all-in-one"-Project), is the most convenient for developing/testing.
    Here the Worker-Process is "shelled" against the same ExeName as the Main- (or Master-) Project,
    using a simple "forking" in Sub Main() ... (as shown below from the content of Demo1 modMain.bas):
    Code:
    Option Explicit
    
    Sub Main() 'Process-Startup-Forking
      If Len(Trim$(Command$)) = 0 Then 'no Cmd-Arg was passed (it was started as the Master-Process)
        fMaster.Show '... so we simply startup the Main-Form
        
      Else 'it was started as a WorkerProcess (pass the CommandLine-Arg into the WorkerRoutine)
        EnterWorkerLoop New cIPCWorker, Trim$(Command$)
      End If
    End Sub
    Above, the blue-colored call represents the "master-fork-path" to your normal "GUI-Project-Code"
    (entered when no Commandline-Param was passed to your Executable).

    And as the magenta-colored routine-name (in the "worker-fork-path") suggests, the upstarting worker is not fired up
    like in an old "classic WebServer-CGI-call" (where the Process exits, after only a single Job was performed).

    Instead the current mechanism is implemented in a way, that the WorkerProcess is fired up once -
    and then enters an "IDLE-loop" (waiting for Jobs, provided by the Master-Process later).
    This way one of the disadvantages of MultiProcessing (the higher Startup-Costs, compared to MultiThreading) is avoided.

    The advantages of doing MultiProcessing instead of threading are:
    - no typelibs, no extra-Dlls are needed
    - in the IDE (after compiling the same Project), the asynchronous workers will behave the same way as in the compiled binary
    - a hard terminate of a worker is possible in a stable and "residue-free" manner (though graceful termination-support is of course built-in)
    - the communication between Master and Worker(s) happens in an absolute "non-blocking" way

    To explain the last point above a bit more... "non-blocking" means, that neither Post- or SendMessage-calls are involved
    (as in VB6-OleBased-Communications between "threaded Apartments", where Events, raised from the Workers will block the Main-Thread) -
    nor are there other mechanisms in play like Mutexes or CriticalSections, which are normally used in conjunction with shared memory...

    Instead the Demo shows, how "state-machine-based" communication (using the shared mem-area) can be implemented.

    The approach is extremely robust, completely IDE- and crash-safe, and "cleans up after itself" under any circumstances:
    - upstarted Worker-Processes will automatically close, when the Master-Class goes out of scope
    - you can even use the IDE-stop-button, whilst asynchronous workers are "deep within a Job" (worker-processes will autoclose nevertheless)

    There is also not a single thing, which is "forbidden to use" in the workers (like in many of the threading-approaches for VB6)...

    The Zip below comes with 3 Demo-Folders (a simple one to get up to speed - and two "medium-difficult" ones for MandelBrot-rendering).

    Ok, here is, what the MandelBrot-Demos will produce (using two Workers, independent from the Main-App):


    And here's the Demo-Zip: IPCSharedMem.zip

    Have fun...

    Olaf
    in demo

    jobPrepared 'set from the Master-Instance
    Private Sub cmdStart_Click()
    M.JobState = jobPrepared '' if JobState= jobPrepared ,in sub "M_JobStateChanged" JobState =processing why ≠ Prepared ? Is it ignored automatically?
    End Sub
    Private Sub M_JobStateChanged(ByVal JobState As eJobState)
    cmdCancel.Enabled = (JobState = jobProcessing)
    cmdStart.Enabled = Not cmdCancel.Enabled
    Caption = M.JobStateFriendlyName ----------------------
    End Sub
    Last edited by xxdoc123; Jun 1st, 2018 at 02:21 AM.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,638

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Yes, apparently the StateSwitch (from jobPrepared to jobProcessing) happens so fast, that the JobStateChanged-Event skips it.

    Well, and besides - it is of no interest for the Master-Process (who initiated that State-Switch in the first place).

    Instead the Master-Process is interested in those State-Switches, which were triggered inside the Worker:
    - jobProcessing (which the Worker switches to, after the Master has signaled it "New Input-Parameters" via jobPrepared
    - jobFinished (which the Worker switches to from jobProcessing, after successful finishing a given Job)

    HTH

    Olaf

  6. #6
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    555

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    When running the program (either the combined or separated programs), one copy appears in the Apps section of the Task Manager, and the other in the Background section. It seems to me that using a separate worker thread would be more efficient from a memory usage perspective. To that end, and to get a better understanding of the internal workings of the program, I converted the Simple Demo into 2 separate programs. I did take a few liberties with the code to make it easier to follow, so I hope you don't mind.

    J.A. Coutts
    Attached Images Attached Images  
    Attached Files Attached Files

  7. #7
    Addicted Member
    Join Date
    Aug 2016
    Posts
    242

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by couttsj View Post
    When running the program (either the combined or separated programs), one copy appears in the Apps section of the Task Manager, and the other in the Background section. It seems to me that using a separate worker thread would be more efficient from a memory usage perspective. To that end, and to get a better understanding of the internal workings of the program, I converted the Simple Demo into 2 separate programs. I did take a few liberties with the code to make it easier to follow, so I hope you don't mind.

    J.A. Coutts
    I have a need is a work process to read the server data used winhttp or your http mod, processed and passed to the control main process to show, do not know if the work process will die. I haven't done this yet.

  8. #8
    Addicted Member
    Join Date
    Aug 2016
    Posts
    242

    Question Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by Schmidt View Post
    This demonstrates, how one can implement robust, asynchronous Workers in VB6 -
    by using a (cross-process) SharedMemory-approach (which is one of the common IPC-mechanisms).

    For convenient usage, the more complex stuff (the MemoryMapping- as well as the CreateProcess-APIs),
    are encapsulated in two generic "Drop-In"-Classes (cIPCMaster and cIPCWorker).

    Those Classes can be used either "split-up" (in separate VB6-Projects for Master and Worker) -
    but also "all-in-one" (when the same Project - or Process - is used to act as Master and Worker both).

    The latter case (using an "all-in-one"-Project), is the most convenient for developing/testing.
    Here the Worker-Process is "shelled" against the same ExeName as the Main- (or Master-) Project,
    using a simple "forking" in Sub Main() ... (as shown below from the content of Demo1 modMain.bas):
    Code:
    Option Explicit
    
    Sub Main() 'Process-Startup-Forking
      If Len(Trim$(Command$)) = 0 Then 'no Cmd-Arg was passed (it was started as the Master-Process)
        fMaster.Show '... so we simply startup the Main-Form
        
      Else 'it was started as a WorkerProcess (pass the CommandLine-Arg into the WorkerRoutine)
        EnterWorkerLoop New cIPCWorker, Trim$(Command$)
      End If
    End Sub
    Above, the blue-colored call represents the "master-fork-path" to your normal "GUI-Project-Code"
    (entered when no Commandline-Param was passed to your Executable).

    And as the magenta-colored routine-name (in the "worker-fork-path") suggests, the upstarting worker is not fired up
    like in an old "classic WebServer-CGI-call" (where the Process exits, after only a single Job was performed).

    Instead the current mechanism is implemented in a way, that the WorkerProcess is fired up once -
    and then enters an "IDLE-loop" (waiting for Jobs, provided by the Master-Process later).
    This way one of the disadvantages of MultiProcessing (the higher Startup-Costs, compared to MultiThreading) is avoided.

    The advantages of doing MultiProcessing instead of threading are:
    - no typelibs, no extra-Dlls are needed
    - in the IDE (after compiling the same Project), the asynchronous workers will behave the same way as in the compiled binary
    - a hard terminate of a worker is possible in a stable and "residue-free" manner (though graceful termination-support is of course built-in)
    - the communication between Master and Worker(s) happens in an absolute "non-blocking" way

    To explain the last point above a bit more... "non-blocking" means, that neither Post- or SendMessage-calls are involved
    (as in VB6-OleBased-Communications between "threaded Apartments", where Events, raised from the Workers will block the Main-Thread) -
    nor are there other mechanisms in play like Mutexes or CriticalSections, which are normally used in conjunction with shared memory...

    Instead the Demo shows, how "state-machine-based" communication (using the shared mem-area) can be implemented.

    The approach is extremely robust, completely IDE- and crash-safe, and "cleans up after itself" under any circumstances:
    - upstarted Worker-Processes will automatically close, when the Master-Class goes out of scope
    - you can even use the IDE-stop-button, whilst asynchronous workers are "deep within a Job" (worker-processes will autoclose nevertheless)

    There is also not a single thing, which is "forbidden to use" in the workers (like in many of the threading-approaches for VB6)...

    The Zip below comes with 3 Demo-Folders (a simple one to get up to speed - and two "medium-difficult" ones for MandelBrot-rendering).

    Ok, here is, what the MandelBrot-Demos will produce (using two Workers, independent from the Main-App):


    And here's the Demo-Zip: IPCSharedMem.zip

    Have fun...

    Olaf
    If I want to pass string data to the shared memory from the main process, how does the working process know the length of the shared string when reading data?


    Public Type RecordType

    str As String * 100 ------Must use a fixed-length string

    End Type

    Now I think of this method to solve this problem

    '====add
    Private Declare Function lstrcpyn _
    Lib "kernel32" _
    Alias "lstrcpynA" (ByVal lpString1 As Any, _
    ByVal lpString2 As Any, _
    ByVal iMaxLength As Long) As Long

    Private Declare Function lstrlen _
    Lib "kernel32" _
    Alias "lstrlenA" (ByVal lpString As Any) As Long
    Private str As String

    Private Sub cmdStart_Click()
    Label2.Caption = ""

    str = "hello:Schmidt" '
    'M.UserDataWrite StrPtr(str), lstrlen(str)
    lstrcpyn M.UserDataPtr, ByVal str, lstrlen(str) + 1
    'MsgBox lstrlen(M.UserDataPtr)
    M.JobState = jobPrepared


    Private Sub DoJob(W As cIPCWorker)

    Dim i As Long

    Dim tmpString As String

    tmpString = Space(lstrlen(W.UserDataPtr))
    lstrcpyn ByVal tmpString, W.UserDataPtr, lstrlen(W.UserDataPtr) + 1

    MsgBox tmpString

    For i = 1 To 100
    W.JobProgress = i / 100
    W.Wait 50 '<- simulate some workload (instead of doing some real stuff)

    If W.MasterWantsToClose Or W.JobState <> wjobProcessing Then Exit Sub 'early exit
    Next
    str = Replace(tmpString, "hello", "thanks")

    lstrcpyn W.UserDataPtr, ByVal str, lstrlen(str) + 1
    W.JobState = wjobFinished 'if the worker-routine reached this point, switch to the next state

    End Sub
    Demo1 Send string.zip

    Do you have other methods?
    Last edited by xxdoc123; Jun 4th, 2018 at 12:38 AM.

  9. #9
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    555

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by xxdoc123 View Post
    I have a need is a work process to read the server data used winhttp or your http mod, processed and passed to the control main process to show, do not know if the work process will die. I haven't done this yet.
    As far as I can tell, the worker thread remains in memory as long as the main thread.

    J.A. Coutts

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,638

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by couttsj View Post
    As far as I can tell, the worker thread remains in memory as long as the main thread.
    To be precise, the WorkerProcess remains alive (assuming your own Worker-Functions don't cause an unhandled VB6-error-condition) until:
    - the cIPCMaster-Object of the Main-Process calls its .CloseWorkerGracefully(TimeOutSeconds) method
    - or is set to Nothing "roughly" (in which case it performs a Hard-Terminate of the Worker-Process)

    There's also a third condition under which a WokerProcess automatically closes itself:
    - if the Form.hWnd one has passed via InitAndBindWorkerTo(...) dies, the Worker will recognize this also and will automatically close
    .. (this is BTW the mechanism which ensures automatic Worker-closing, when you press the Stop-Button in the IDE)

    Ok, so the only other condition (the fourth one) under which a WorkerProcess can "go out" is the one I mentioned at the top of this posting:
    - you run into an unhandled error-condition in your own Worker-Code
    A cIPCMaster-Instance in your Main-App-Thread can always ask, whether a Worker ran into such a condition (is still alive) via:
    oMaster.IsWorkerActive

    If you poll that IsWorkerActive-Property against a given cIPCMaster-Instance, (e.g. when you manage a few of them in
    a dedicated "Worker-Pool-Manager-Class") - you could easily react to "unexpected closing" of a worker, by removing
    said Master-instance (which only refers to a "dead worker") from your "Worker-Pool-Collection" - readding a new one instead.
    This allows for an easy way to set up a real stable-working "WorkerPool-Manager-Process" (e.g. for a robust Server-Scenario).

    As to your other question:
    It seems to me that using a separate worker thread would be more efficient from a memory usage perspective.
    An upstarted VB-Process (with no GUI) consumes about 1.5MB of memory...
    So, yes - that's a bit more overhead than an upstarting "normal thread" would consume (memory-wise).
    But these days, I'd consider that amount of memory-overhead not really "an issue" (even if you run a pool of 16 Workers or so).

    HTH

    Olaf

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,638

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by xxdoc123 View Post
    If I want to pass string data to the shared memory from the main process, how does the working process know the length of the shared string when reading data?

    Now I think of this method to solve this problem...

    Do you have other methods?
    There is no need to apply a (non-unicode-capable) API for that.

    I'd simply:
    - define all Strings of a Shared-Memory-Area as fixed-length-string-members of an UDT
    - then later always read (or write) the entire UDT-content from (or to) the Shared-Area via: UserDataWrite VarPtr(MyUDT), LenB(MyUDT)
    - and for "InBetween" happening changes of the UDTs FixedLength-StringMembers I'd use a simple "Property-Helper" like shown below:

    Code:
    Option Explicit
    
    Private Type tMyUDT
      S As String * 100
    End Type
    
    Private Sub Form_Load()
      Dim MyUDT As tMyUDT
      Debug.Print Len(FLS(MyUDT.S)), FLS(MyUDT.S) 'print the S-member content from a fresh initialized UDT
      
      FLS(MyUDT.S) = "123": Debug.Print Len(FLS(MyUDT.S)), FLS(MyUDT.S) 'print it after assigning "123"
      FLS(MyUDT.S) = "":    Debug.Print Len(FLS(MyUDT.S)), FLS(MyUDT.S) 'print it again, after assigning ""
    End Sub
    
    Private Property Let FLS(FLSmember As String, RHS As String)
      If Len(FLSmember) <= Len(RHS) Then Err.Raise 7
      FLSmember = RHS & vbNullChar
    End Property
    Private Property Get FLS(FLSmember As String) As String
      Dim Pos As Long: Pos = InStr(FLSmember, vbNullChar)
      If Pos > 0 Then FLS = Left$(FLSmember, Pos - 1)
    End Property
    Olaf

  12. #12

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,638

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by couttsj View Post
    ... to get a better understanding of the internal workings of the program, I converted the Simple Demo into 2 separate programs.
    I did take a few liberties with the code to make it easier to follow, so I hope you don't mind.
    Just tried to run your Demo1B.zip above... -
    though it seems you forgot to include a Sub Main() triggering of EnterWorkerLoop within your modWorker.bas:
    Code:
    Sub Main()
      If Len(Trim$(Command$)) Then EnterWorkerLoop New cIPCWorker, Trim$(Command$)
    End Sub
    Olaf

  13. #13
    Addicted Member
    Join Date
    Aug 2016
    Posts
    242

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by Schmidt View Post
    There is no need to apply a (non-unicode-capable) API for that.

    I'd simply:
    - define all Strings of a Shared-Memory-Area as fixed-length-string-members of an UDT
    - then later always read (or write) the entire UDT-content from (or to) the Shared-Area via: UserDataWrite VarPtr(MyUDT), LenB(MyUDT)
    - and for "InBetween" happening changes of the UDTs FixedLength-StringMembers I'd use a simple "Property-Helper" like shown below:

    Code:
    Option Explicit
    
    Private Type tMyUDT
      S As String * 100
    End Type
    
    Private Sub Form_Load()
      Dim MyUDT As tMyUDT
      Debug.Print Len(FLS(MyUDT.S)), FLS(MyUDT.S) 'print the S-member content from a fresh initialized UDT
      
      FLS(MyUDT.S) = "123": Debug.Print Len(FLS(MyUDT.S)), FLS(MyUDT.S) 'print it after assigning "123"
      FLS(MyUDT.S) = "":    Debug.Print Len(FLS(MyUDT.S)), FLS(MyUDT.S) 'print it again, after assigning ""
    End Sub
    
    Private Property Let FLS(FLSmember As String, RHS As String)
      If Len(FLSmember) <= Len(RHS) Then Err.Raise 7
      FLSmember = RHS & vbNullChar
    End Property
    Private Property Get FLS(FLSmember As String) As String
      Dim Pos As Long: Pos = InStr(FLSmember, vbNullChar)
      If Pos > 0 Then FLS = Left$(FLSmember, Pos - 1)
    End Property
    Olaf
    thanks .

    I have a suggestion to add a length shared variable in the two class module. You can directly return the length

    Private Type tShared 'a convenience-UDT, sitting at the top of the shared mem-area
    UserDataLen As Long
    MasterHwnd As Long
    JobProgress As Single
    JobPreparedHPSec As Double
    JobStartedHPSec As Double
    JobFinishedHPSec As Double
    JobState As eJobState
    UserWriteDataLen As Long '
    End Type
    Public Sub UserDataWrite(ByVal pSrc As Long, _
    ByVal ByteLen As Long, _
    Optional ByVal Offs As Long)

    If BaseAddr Then
    RtlMoveMemory ByVal UserDataPtr + Offs, ByVal pSrc, ByteLen
    T.UserWriteDataLen = ByteLen
    WriteInternalType T
    End If
    End Sub
    I can know the length of the currently written data, and if it needs to be read, I can initialize the length of the variable.

  14. #14
    Fanatic Member
    Join Date
    Dec 2012
    Posts
    555

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by Schmidt View Post
    Just tried to run your Demo1B.zip above... -
    though it seems you forgot to include a Sub Main() triggering of EnterWorkerLoop within your modWorker.bas:
    Olaf
    You are right! Don't know how I managed that. Probably added it, created the executable, and created the zip without saving the file. Anyway, I added a message to tell me I can't run it in the IDE.
    Code:
    Sub Main()
        If Len(Trim$(Command$)) Then
            EnterWorkerLoop New cIPCWorker, Trim$(Command$)
        Else
            MsgBox "To be able to start a Worker, this Project needs to be compiled first"
        End If
    End Sub
    Still looking for an appropriate application to use this.

    J.A. Coutts

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    3,638

    Re: VB6 MultiProcessing (StdExe-IPC via SharedMemory)

    Quote Originally Posted by couttsj View Post
    Still looking for an appropriate application to use this.
    We use it (at the place where I currently work) for one type of special report (which takes quite long to generate, interacting with MS-Word-XML) -
    and as well for validation of larger amounts of Email-addresses (which involve DNS-queries with potentially longer blocking whilst asking for MX-record-entries)...

    Basically it has the same async use-cases as threading, but the advantage of being more robust -
    due to allowing for "proper-cleanup of single Workers from a WorkerPool" without affecting the "Pool-Hosting-App".

    Also device-communication for time-critical (e.g. streaming-) devices comes to mind (one Worker being responsible for exactly one device).
    Over a decade ago, I've used a quite similar approach to manage the incoming DataStreams from up to 12 Gig-E cameras, which pumped
    their incoming frames with 200Hz each into a larger RingBuffer in each WorkerProcess (on a quite powerful Server-Host, which ran 24/7).

    Olaf

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width


×
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.