User Tools

Site Tools


sharing_20a_20structure_20between_20processes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sharing_20a_20structure_20between_20processes [2018/03/31 13:19]
127.0.0.1 external edit
sharing_20a_20structure_20between_20processes [2018/04/17 18:42] (current)
tbest3112 Added syntax highlighting
Line 2: Line 2:
  
 //by Richard Russell, October 2014//\\ \\  Most modern PCs have multiple CPU cores, often four or more. If you are creating a computationally-intensive application you may wish to take advantage of this feature, but that is not so easy to do in BBC BASIC. One approach is to code some of the functionality in assembly language (using the built-in assembler) which can be arranged to run in a separate thread, and therefore potentially on a different core. However this requires specialised skills which not all BASIC programmers can be expected to acquire; debugging assembler code can also be difficult.\\ \\  If you are coding purely in BASIC there is really only one way to take advantage of multiple CPU cores, and that is to run multiple executables,​ and hence multiple processes - Windows will then automatically allocate the different processes to different cores if available. Depending on the nature of your application these may be multiple copies of the **same** executable, if it is possible to subdivide the task in this way, or executables compiled from different BASIC sub-programs.\\ \\  Either way there is very likely to be a need for the multiple processes to communicate with each other, in order to coordinate the work. In Windows there are many possible types of [[http://​msdn.microsoft.com/​en-gb/​library/​windows/​desktop/​aa365574.aspx|Inter Process Communication]] (IPC), all of which may be used by BBC BASIC programs with more or less difficulty. One particularly convenient method is the ability to **share** a data structure between processes; even though your different executables will be running in quite separate address spaces you can arrange that the structure is visible to them all!\\ \\  This is surprisingly easy to achieve. To do so you should incorporate the following code in the initialisation routines of **all** the programs that need to share the structure:​\\ \\  //by Richard Russell, October 2014//\\ \\  Most modern PCs have multiple CPU cores, often four or more. If you are creating a computationally-intensive application you may wish to take advantage of this feature, but that is not so easy to do in BBC BASIC. One approach is to code some of the functionality in assembly language (using the built-in assembler) which can be arranged to run in a separate thread, and therefore potentially on a different core. However this requires specialised skills which not all BASIC programmers can be expected to acquire; debugging assembler code can also be difficult.\\ \\  If you are coding purely in BASIC there is really only one way to take advantage of multiple CPU cores, and that is to run multiple executables,​ and hence multiple processes - Windows will then automatically allocate the different processes to different cores if available. Depending on the nature of your application these may be multiple copies of the **same** executable, if it is possible to subdivide the task in this way, or executables compiled from different BASIC sub-programs.\\ \\  Either way there is very likely to be a need for the multiple processes to communicate with each other, in order to coordinate the work. In Windows there are many possible types of [[http://​msdn.microsoft.com/​en-gb/​library/​windows/​desktop/​aa365574.aspx|Inter Process Communication]] (IPC), all of which may be used by BBC BASIC programs with more or less difficulty. One particularly convenient method is the ability to **share** a data structure between processes; even though your different executables will be running in quite separate address spaces you can arrange that the structure is visible to them all!\\ \\  This is surprisingly easy to achieve. To do so you should incorporate the following code in the initialisation routines of **all** the programs that need to share the structure:​\\ \\ 
 +<code bb4w>
         FILE_MAP_WRITE = 2         FILE_MAP_WRITE = 2
         PAGE_READWRITE = 4         PAGE_READWRITE = 4
Line 12: Line 13:
         IF pShared% = 0 ERROR 0, "​Couldn'​t map view of file"         IF pShared% = 0 ERROR 0, "​Couldn'​t map view of file"
         !(^Shared{}+4) = pShared%         !(^Shared{}+4) = pShared%
 +</​code>​
 The string shown as **"​unique string"​** must be unique to your application;​ to guarantee that you don't accidentally use the same string as another program the best choice is a [[/​Creating%20a%20Globally%20Unique%20Identifier|Globally Unique Identifier]] (GUID).\\ \\  Note that the structure can contain any valid member types **except** ordinary (moveable) strings or string arrays (e.g. member$). If you want to share strings use NUL-terminated arrays of characters such as **member&​(255)** which can be accessed as follows:​\\ ​ The string shown as **"​unique string"​** must be unique to your application;​ to guarantee that you don't accidentally use the same string as another program the best choice is a [[/​Creating%20a%20Globally%20Unique%20Identifier|Globally Unique Identifier]] (GUID).\\ \\  Note that the structure can contain any valid member types **except** ordinary (moveable) strings or string arrays (e.g. member$). If you want to share strings use NUL-terminated arrays of characters such as **member&​(255)** which can be accessed as follows:​\\ ​
 +<code bb4w>
         Shared.member&​() = "Hello world!"​         Shared.member&​() = "Hello world!"​
         PRINT Shared.member&​()         PRINT Shared.member&​()
 +</​code>​
 In your program'​s '​cleanup'​ routine include the following code:​\\ ​ In your program'​s '​cleanup'​ routine include the following code:​\\ ​
 +<code bb4w>
         pShared% += 0 : IF pShared% SYS "​UnmapViewOfFile",​ pShared% : pShared% = 0         pShared% += 0 : IF pShared% SYS "​UnmapViewOfFile",​ pShared% : pShared% = 0
         hMap% += 0 : IF hMap% SYS "​CloseHandle",​ hMap% : hMap% = 0         hMap% += 0 : IF hMap% SYS "​CloseHandle",​ hMap% : hMap% = 0
 +</​code>​
 It is extremely important that two or more processes don't attempt to write to the same structure member at the same time. The safest way to guarantee that is for each structure member to be writable only by **one** of your processes, and read-only to all the others.\\ \\  Also, be aware of the possibility that the data read by one process may be invalid because it is concurrently being written by another process (if it's an aligned 32-bit integer you can probably be assured of an '​atomic'​ update, but not with larger data types). If this is a concern you can use a **mutex** to prevent concurrent access. It is extremely important that two or more processes don't attempt to write to the same structure member at the same time. The safest way to guarantee that is for each structure member to be writable only by **one** of your processes, and read-only to all the others.\\ \\  Also, be aware of the possibility that the data read by one process may be invalid because it is concurrently being written by another process (if it's an aligned 32-bit integer you can probably be assured of an '​atomic'​ update, but not with larger data types). If this is a concern you can use a **mutex** to prevent concurrent access.
sharing_20a_20structure_20between_20processes.txt ยท Last modified: 2018/04/17 18:42 by tbest3112