We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
callback_server.py example error
<!--
Please use the Pymodbus gitter channel at https://gitter.im/pymodbus_dev/Lobby or Stack Overflow(tag [pymodbus](https://stackoverflow.com/questions/tagged/pymodbus) for
support questions.

Before opening a new issue, make sure you do the following:
    * check that your issue isn't already filed: https://github.com/riptideio/pymodbus/issues
    * prepare a short, runnable example that reproduce the issue with the latest development version of Pymodbus
-->

### Versions

* Python: 3.7
* OS: Ubuntu 20
* Pymodbus: 2.5.0
* Modbus Hardware (if used): 

### Pymodbus Specific
* Server: rtu - sync
* Client: rtu - sync

### Description

When I adapt the "callback_server.py" example, I make the queue client modify the datastore, but my client doesn't see the changes.
after some work, it's due to the use of Process creation for the queue listener that makes changes in it's own scope.

### Correction
change the queue Process listener creation :
```python
    p = Process(target=device_writer, args=(queue,))
    p.start()
```
by a Thread queue listenrer makes changes could be seen by my client because of modification made in the same server scope:
```python
from threading import Thread
...
     t = Thread(target = device_writer, args=(queue,))
    t.start()
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `examples/common/callback_server.py`
Content:
```
1 #!/usr/bin/env python3
2 # pylint: disable=missing-type-doc,missing-param-doc,differing-param-doc
3 """Pymodbus Server With Callbacks.
4 
5 This is an example of adding callbacks to a running modbus server
6 when a value is written to it. In order for this to work, it needs
7 a device-mapping file.
8 """
9 import logging
10 from multiprocessing import Queue, Process
11 
12 # --------------------------------------------------------------------------- #
13 # import the modbus libraries we need
14 # --------------------------------------------------------------------------- #
15 from pymodbus.version import version
16 from pymodbus.server.asynchronous import StartTcpServer
17 from pymodbus.device import ModbusDeviceIdentification
18 from pymodbus.datastore import ModbusSparseDataBlock
19 from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
20 
21 # from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer
22 
23 
24 # --------------------------------------------------------------------------- #
25 # configure the service logging
26 # --------------------------------------------------------------------------- #
27 log = logging.getLogger()
28 log.setLevel(logging.DEBUG)
29 
30 # --------------------------------------------------------------------------- #
31 # create your custom data block with callbacks
32 # --------------------------------------------------------------------------- #
33 
34 
35 class CallbackDataBlock(ModbusSparseDataBlock):
36     """A datablock that stores the new value in memory,
37 
38     and passes the operation to a message queue for further processing.
39     """
40 
41     def __init__(self, devices, queue):
42         """Initialize."""
43         self.devices = devices
44         self.queue = queue
45 
46         values = {k: 0 for k in devices.keys()}
47         values[0xBEEF] = len(values)  # the number of devices
48         super().__init__(values)
49 
50     def setValues(self, address, value):  # pylint: disable=arguments-differ
51         """Set the requested values of the datastore
52 
53         :param address: The starting address
54         :param values: The new values to be set
55         """
56         super().setValues(address, value)
57         self.queue.put((self.devices.get(address, None), value))
58 
59 
60 # --------------------------------------------------------------------------- #
61 # define your callback process
62 # --------------------------------------------------------------------------- #
63 
64 
65 def rescale_value(value):
66     """Rescale the input value from the range of 0..100 to -3200..3200.
67 
68     :param value: The input value to scale
69     :returns: The rescaled value
70     """
71     scale = 1 if value >= 50 else -1
72     cur = value if value < 50 else (value - 50)
73     return scale * (cur * 64)
74 
75 
76 def device_writer(queue):
77     """Process new messages from a queue to write to device outputs
78 
79     :param queue: The queue to get new messages from
80     """
81     while True:
82         device, value = queue.get()
83         rescale_value(value[0])
84         txt = f"Write({device}) = {value}"
85         log.debug(txt)
86         if not device:
87             continue
88         # do any logic here to update your devices
89 
90 
91 # --------------------------------------------------------------------------- #
92 # initialize your device map
93 # --------------------------------------------------------------------------- #
94 
95 
96 def read_device_map(path):
97     """Read the device path to address mapping from file::
98 
99        0x0001,/dev/device1
100        0x0002,/dev/device2
101 
102     :param path: The path to the input file
103     :returns: The input mapping file
104     """
105     devices = {}
106     with open(path, "r") as stream:  # pylint: disable=unspecified-encoding
107         for line in stream:
108             piece = line.strip().split(",")
109             devices[int(piece[0], 16)] = piece[1]
110     return devices
111 
112 
113 def run_callback_server():
114     """Run callback server."""
115     # ----------------------------------------------------------------------- #
116     # initialize your data store
117     # ----------------------------------------------------------------------- #
118     queue = Queue()
119     devices = read_device_map("device-mapping")
120     block = CallbackDataBlock(devices, queue)
121     store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
122     context = ModbusServerContext(slaves=store, single=True)
123 
124     # ----------------------------------------------------------------------- #
125     # initialize the server information
126     # ----------------------------------------------------------------------- #
127     identity = ModbusDeviceIdentification(
128         info_name={
129             "VendorName": "pymodbus",
130             "ProductCode": "PM",
131             "VendorUrl": "http://github.com/riptideio/pymodbus/",
132             "ProductName": "pymodbus Server",
133             "ModelName": "pymodbus Server",
134             "MajorMinorRevision": version.short(),
135         }
136     )
137 
138     # ----------------------------------------------------------------------- #
139     # run the server you want
140     # ----------------------------------------------------------------------- #
141     proc = Process(target=device_writer, args=(queue,))
142     proc.start()
143     StartTcpServer(context, identity=identity, address=("localhost", 5020))
144 
145 
146 if __name__ == "__main__":
147     run_callback_server()
148
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/examples/common/callback_server.py b/examples/common/callback_server.py
--- a/examples/common/callback_server.py
+++ b/examples/common/callback_server.py
@@ -7,7 +7,8 @@
 a device-mapping file.
 """
 import logging
-from multiprocessing import Queue, Process
+from multiprocessing import Queue
+from threading import Thread
 
 # --------------------------------------------------------------------------- #
 # import the modbus libraries we need
@@ -138,8 +139,8 @@
     # ----------------------------------------------------------------------- #
     # run the server you want
     # ----------------------------------------------------------------------- #
-    proc = Process(target=device_writer, args=(queue,))
-    proc.start()
+    thread = Thread(target=device_writer, args=(queue,))
+    thread.start()
     StartTcpServer(context, identity=identity, address=("localhost", 5020))

{"golden_diff": "diff --git a/examples/common/callback_server.py b/examples/common/callback_server.py\n--- a/examples/common/callback_server.py\n+++ b/examples/common/callback_server.py\n@@ -7,7 +7,8 @@\n a device-mapping file.\n \"\"\"\n import logging\n-from multiprocessing import Queue, Process\n+from multiprocessing import Queue\n+from threading import Thread\n \n # --------------------------------------------------------------------------- #\n # import the modbus libraries we need\n@@ -138,8 +139,8 @@\n     # ----------------------------------------------------------------------- #\n     # run the server you want\n     # ----------------------------------------------------------------------- #\n-    proc = Process(target=device_writer, args=(queue,))\n-    proc.start()\n+    thread = Thread(target=device_writer, args=(queue,))\n+    thread.start()\n     StartTcpServer(context, identity=identity, address=(\"localhost\", 5020))\n", "issue": "callback_server.py example error\n<!--\r\nPlease use the Pymodbus gitter channel at https://gitter.im/pymodbus_dev/Lobby or Stack Overflow(tag [pymodbus](https://stackoverflow.com/questions/tagged/pymodbus) for\r\nsupport questions.\r\n\r\nBefore opening a new issue, make sure you do the following:\r\n    * check that your issue isn't already filed: https://github.com/riptideio/pymodbus/issues\r\n    * prepare a short, runnable example that reproduce the issue with the latest development version of Pymodbus\r\n-->\r\n\r\n### Versions\r\n\r\n* Python: 3.7\r\n* OS: Ubuntu 20\r\n* Pymodbus: 2.5.0\r\n* Modbus Hardware (if used): \r\n\r\n### Pymodbus Specific\r\n* Server: rtu - sync\r\n* Client: rtu - sync\r\n\r\n### Description\r\n\r\nWhen I adapt the \"callback_server.py\" example, I make the queue client modify the datastore, but my client doesn't see the changes.\r\nafter some work, it's due to the use of Process creation for the queue listener that makes changes in it's own scope.\r\n\r\n### Correction\r\nchange the queue Process listener creation :\r\n```python\r\n    p = Process(target=device_writer, args=(queue,))\r\n    p.start()\r\n```\r\nby a Thread queue listenrer makes changes could be seen by my client because of modification made in the same server scope:\r\n```python\r\nfrom threading import Thread\r\n...\r\n     t = Thread(target = device_writer, args=(queue,))\r\n    t.start()\r\n```\r\n\n", "before_files": [{"content": "#!/usr/bin/env python3\n# pylint: disable=missing-type-doc,missing-param-doc,differing-param-doc\n\"\"\"Pymodbus Server With Callbacks.\n\nThis is an example of adding callbacks to a running modbus server\nwhen a value is written to it. In order for this to work, it needs\na device-mapping file.\n\"\"\"\nimport logging\nfrom multiprocessing import Queue, Process\n\n# --------------------------------------------------------------------------- #\n# import the modbus libraries we need\n# --------------------------------------------------------------------------- #\nfrom pymodbus.version import version\nfrom pymodbus.server.asynchronous import StartTcpServer\nfrom pymodbus.device import ModbusDeviceIdentification\nfrom pymodbus.datastore import ModbusSparseDataBlock\nfrom pymodbus.datastore import ModbusSlaveContext, ModbusServerContext\n\n# from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer\n\n\n# --------------------------------------------------------------------------- #\n# configure the service logging\n# --------------------------------------------------------------------------- #\nlog = logging.getLogger()\nlog.setLevel(logging.DEBUG)\n\n# --------------------------------------------------------------------------- #\n# create your custom data block with callbacks\n# --------------------------------------------------------------------------- #\n\n\nclass CallbackDataBlock(ModbusSparseDataBlock):\n    \"\"\"A datablock that stores the new value in memory,\n\n    and passes the operation to a message queue for further processing.\n    \"\"\"\n\n    def __init__(self, devices, queue):\n        \"\"\"Initialize.\"\"\"\n        self.devices = devices\n        self.queue = queue\n\n        values = {k: 0 for k in devices.keys()}\n        values[0xBEEF] = len(values)  # the number of devices\n        super().__init__(values)\n\n    def setValues(self, address, value):  # pylint: disable=arguments-differ\n        \"\"\"Set the requested values of the datastore\n\n        :param address: The starting address\n        :param values: The new values to be set\n        \"\"\"\n        super().setValues(address, value)\n        self.queue.put((self.devices.get(address, None), value))\n\n\n# --------------------------------------------------------------------------- #\n# define your callback process\n# --------------------------------------------------------------------------- #\n\n\ndef rescale_value(value):\n    \"\"\"Rescale the input value from the range of 0..100 to -3200..3200.\n\n    :param value: The input value to scale\n    :returns: The rescaled value\n    \"\"\"\n    scale = 1 if value >= 50 else -1\n    cur = value if value < 50 else (value - 50)\n    return scale * (cur * 64)\n\n\ndef device_writer(queue):\n    \"\"\"Process new messages from a queue to write to device outputs\n\n    :param queue: The queue to get new messages from\n    \"\"\"\n    while True:\n        device, value = queue.get()\n        rescale_value(value[0])\n        txt = f\"Write({device}) = {value}\"\n        log.debug(txt)\n        if not device:\n            continue\n        # do any logic here to update your devices\n\n\n# --------------------------------------------------------------------------- #\n# initialize your device map\n# --------------------------------------------------------------------------- #\n\n\ndef read_device_map(path):\n    \"\"\"Read the device path to address mapping from file::\n\n       0x0001,/dev/device1\n       0x0002,/dev/device2\n\n    :param path: The path to the input file\n    :returns: The input mapping file\n    \"\"\"\n    devices = {}\n    with open(path, \"r\") as stream:  # pylint: disable=unspecified-encoding\n        for line in stream:\n            piece = line.strip().split(\",\")\n            devices[int(piece[0], 16)] = piece[1]\n    return devices\n\n\ndef run_callback_server():\n    \"\"\"Run callback server.\"\"\"\n    # ----------------------------------------------------------------------- #\n    # initialize your data store\n    # ----------------------------------------------------------------------- #\n    queue = Queue()\n    devices = read_device_map(\"device-mapping\")\n    block = CallbackDataBlock(devices, queue)\n    store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)\n    context = ModbusServerContext(slaves=store, single=True)\n\n    # ----------------------------------------------------------------------- #\n    # initialize the server information\n    # ----------------------------------------------------------------------- #\n    identity = ModbusDeviceIdentification(\n        info_name={\n            \"VendorName\": \"pymodbus\",\n            \"ProductCode\": \"PM\",\n            \"VendorUrl\": \"http://github.com/riptideio/pymodbus/\",\n            \"ProductName\": \"pymodbus Server\",\n            \"ModelName\": \"pymodbus Server\",\n            \"MajorMinorRevision\": version.short(),\n        }\n    )\n\n    # ----------------------------------------------------------------------- #\n    # run the server you want\n    # ----------------------------------------------------------------------- #\n    proc = Process(target=device_writer, args=(queue,))\n    proc.start()\n    StartTcpServer(context, identity=identity, address=(\"localhost\", 5020))\n\n\nif __name__ == \"__main__\":\n    run_callback_server()\n", "path": "examples/common/callback_server.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n# pylint: disable=missing-type-doc,missing-param-doc,differing-param-doc\n\"\"\"Pymodbus Server With Callbacks.\n\nThis is an example of adding callbacks to a running modbus server\nwhen a value is written to it. In order for this to work, it needs\na device-mapping file.\n\"\"\"\nimport logging\nfrom multiprocessing import Queue\nfrom threading import Thread\n\n# --------------------------------------------------------------------------- #\n# import the modbus libraries we need\n# --------------------------------------------------------------------------- #\nfrom pymodbus.version import version\nfrom pymodbus.server.asynchronous import StartTcpServer\nfrom pymodbus.device import ModbusDeviceIdentification\nfrom pymodbus.datastore import ModbusSparseDataBlock\nfrom pymodbus.datastore import ModbusSlaveContext, ModbusServerContext\n\n# from pymodbus.transaction import ModbusRtuFramer, ModbusAsciiFramer\n\n\n# --------------------------------------------------------------------------- #\n# configure the service logging\n# --------------------------------------------------------------------------- #\nlog = logging.getLogger()\nlog.setLevel(logging.DEBUG)\n\n# --------------------------------------------------------------------------- #\n# create your custom data block with callbacks\n# --------------------------------------------------------------------------- #\n\n\nclass CallbackDataBlock(ModbusSparseDataBlock):\n    \"\"\"A datablock that stores the new value in memory,\n\n    and passes the operation to a message queue for further processing.\n    \"\"\"\n\n    def __init__(self, devices, queue):\n        \"\"\"Initialize.\"\"\"\n        self.devices = devices\n        self.queue = queue\n\n        values = {k: 0 for k in devices.keys()}\n        values[0xBEEF] = len(values)  # the number of devices\n        super().__init__(values)\n\n    def setValues(self, address, value):  # pylint: disable=arguments-differ\n        \"\"\"Set the requested values of the datastore\n\n        :param address: The starting address\n        :param values: The new values to be set\n        \"\"\"\n        super().setValues(address, value)\n        self.queue.put((self.devices.get(address, None), value))\n\n\n# --------------------------------------------------------------------------- #\n# define your callback process\n# --------------------------------------------------------------------------- #\n\n\ndef rescale_value(value):\n    \"\"\"Rescale the input value from the range of 0..100 to -3200..3200.\n\n    :param value: The input value to scale\n    :returns: The rescaled value\n    \"\"\"\n    scale = 1 if value >= 50 else -1\n    cur = value if value < 50 else (value - 50)\n    return scale * (cur * 64)\n\n\ndef device_writer(queue):\n    \"\"\"Process new messages from a queue to write to device outputs\n\n    :param queue: The queue to get new messages from\n    \"\"\"\n    while True:\n        device, value = queue.get()\n        rescale_value(value[0])\n        txt = f\"Write({device}) = {value}\"\n        log.debug(txt)\n        if not device:\n            continue\n        # do any logic here to update your devices\n\n\n# --------------------------------------------------------------------------- #\n# initialize your device map\n# --------------------------------------------------------------------------- #\n\n\ndef read_device_map(path):\n    \"\"\"Read the device path to address mapping from file::\n\n       0x0001,/dev/device1\n       0x0002,/dev/device2\n\n    :param path: The path to the input file\n    :returns: The input mapping file\n    \"\"\"\n    devices = {}\n    with open(path, \"r\") as stream:  # pylint: disable=unspecified-encoding\n        for line in stream:\n            piece = line.strip().split(\",\")\n            devices[int(piece[0], 16)] = piece[1]\n    return devices\n\n\ndef run_callback_server():\n    \"\"\"Run callback server.\"\"\"\n    # ----------------------------------------------------------------------- #\n    # initialize your data store\n    # ----------------------------------------------------------------------- #\n    queue = Queue()\n    devices = read_device_map(\"device-mapping\")\n    block = CallbackDataBlock(devices, queue)\n    store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)\n    context = ModbusServerContext(slaves=store, single=True)\n\n    # ----------------------------------------------------------------------- #\n    # initialize the server information\n    # ----------------------------------------------------------------------- #\n    identity = ModbusDeviceIdentification(\n        info_name={\n            \"VendorName\": \"pymodbus\",\n            \"ProductCode\": \"PM\",\n            \"VendorUrl\": \"http://github.com/riptideio/pymodbus/\",\n            \"ProductName\": \"pymodbus Server\",\n            \"ModelName\": \"pymodbus Server\",\n            \"MajorMinorRevision\": version.short(),\n        }\n    )\n\n    # ----------------------------------------------------------------------- #\n    # run the server you want\n    # ----------------------------------------------------------------------- #\n    thread = Thread(target=device_writer, args=(queue,))\n    thread.start()\n    StartTcpServer(context, identity=identity, address=(\"localhost\", 5020))\n\n\nif __name__ == \"__main__\":\n    run_callback_server()\n", "path": "examples/common/callback_server.py"}]}