or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants.mdindex.mdmessage-queues.mdsemaphores.mdshared-memory.md

shared-memory.mddocs/

0

# Shared Memory

1

2

POSIX named shared memory segments provide high-performance inter-process data sharing through memory mapping. Shared memory segments appear as files in the filesystem and can be memory-mapped for direct access, making them ideal for sharing large amounts of data between processes with minimal overhead.

3

4

## Capabilities

5

6

### Shared Memory Creation and Management

7

8

Create and manage named POSIX shared memory segments with configurable size, permissions, and access modes.

9

10

```python { .api }

11

class SharedMemory:

12

def __init__(self, name, flags=0, mode=0o600, size=0, read_only=False):

13

"""

14

Create or open a named shared memory segment.

15

16

Parameters:

17

- name: str or None. If None, a random name is chosen. If str, should start with '/' (e.g., '/my_shared_memory')

18

- flags: int, creation flags (O_CREAT, O_EXCL, O_CREX, O_TRUNC)

19

- mode: int, permissions (octal, default 0o600)

20

- size: int, size in bytes (0 to use existing size)

21

- read_only: bool, whether to open in read-only mode

22

23

Notes:

24

- If size > 0, segment will be resized using ftruncate() regardless of new/existing status

25

- O_TRUNC can be used to truncate existing segment to zero bytes (not supported on macOS)

26

- On macOS, ftruncate() can only be called once during segment lifetime

27

"""

28

```

29

30

### Resource Management

31

32

Properly close file descriptors and clean up shared memory resources.

33

34

```python { .api }

35

def close_fd(self):

36

"""

37

Close the file descriptor associated with this SharedMemory object.

38

39

Equivalent to calling os.close() on the fd attribute. Must be called explicitly -

40

file descriptor is not closed automatically on garbage collection.

41

42

Note: Closing the file descriptor has no effect on any mmap objects created from it.

43

"""

44

45

def fileno(self):

46

"""

47

Returns the file descriptor for the shared memory segment.

48

49

Returns:

50

int: File descriptor (same as the fd property)

51

52

This method allows SharedMemory objects to be used with functions

53

that expect file-like objects with a fileno() method.

54

"""

55

56

def unlink(self):

57

"""

58

Mark the shared memory segment for destruction.

59

60

The segment is destroyed once all processes have unmapped it. Per POSIX spec,

61

after unlinking, subsequent shm_open() calls with the same name will either

62

fail (if O_CREAT not set) or create a new segment (if O_CREAT set).

63

64

Note: Implementation behavior may vary across operating systems.

65

"""

66

67

def __str__(self):

68

"""

69

String representation of the shared memory segment.

70

71

Returns:

72

str: Human-readable representation including name and size

73

"""

74

75

def __repr__(self):

76

"""

77

Detailed string representation for debugging.

78

79

Returns:

80

str: Technical representation with class name and key attributes

81

"""

82

```

83

84

### Shared Memory Properties

85

86

Access shared memory metadata and file descriptor.

87

88

```python { .api }

89

@property

90

def name(self):

91

"""

92

The name provided in the constructor.

93

94

Returns:

95

str: Shared memory segment name

96

"""

97

98

@property

99

def mode(self):

100

"""

101

The mode (permissions) provided in the constructor.

102

103

Returns:

104

int: File mode/permissions (e.g., 0o600)

105

"""

106

107

@property

108

def fd(self):

109

"""

110

File descriptor representing the shared memory segment.

111

112

Returns:

113

int: File descriptor that can be used with os.read(), os.write(), mmap.mmap(), etc.

114

"""

115

116

@property

117

def size(self):

118

"""

119

Current size of the shared memory segment in bytes.

120

121

Returns:

122

int: Size in bytes

123

"""

124

```

125

126

### Module Function

127

128

Convenience function for unlinking shared memory segments by name.

129

130

```python { .api }

131

def unlink_shared_memory(name):

132

"""

133

Convenience function to unlink a shared memory segment by name.

134

135

Parameters:

136

- name: str, shared memory segment name (e.g., '/my_shared_memory')

137

138

Equivalent to opening the segment and calling unlink(), but more convenient

139

when you only need to remove an existing segment.

140

"""

141

```

142

143

## Usage Examples

144

145

### Basic Shared Memory Usage

146

147

```python

148

import posix_ipc

149

import os

150

151

# Create a 1KB shared memory segment

152

shm = posix_ipc.SharedMemory('/my_shm', posix_ipc.O_CREAT, size=1024)

153

154

# Write data using file descriptor

155

data = b'Hello, shared memory!'

156

os.write(shm.fd, data)

157

158

# Read data back

159

os.lseek(shm.fd, 0, os.SEEK_SET) # Reset to beginning

160

read_data = os.read(shm.fd, len(data))

161

print(f"Read: {read_data.decode()}")

162

163

# Clean up

164

shm.close_fd()

165

shm.unlink()

166

```

167

168

### Memory Mapping for High Performance

169

170

```python

171

import posix_ipc

172

import mmap

173

import struct

174

175

# Create shared memory segment

176

shm = posix_ipc.SharedMemory('/mapped_shm', posix_ipc.O_CREAT, size=4096)

177

178

# Memory map the segment

179

mm = mmap.mmap(shm.fd, shm.size)

180

181

# Write structured data directly to memory

182

mm[0:4] = struct.pack('i', 42) # Write integer at offset 0

183

mm[4:12] = b'Hello!!!!' # Write string at offset 4

184

185

# Read structured data

186

value = struct.unpack('i', mm[0:4])[0] # Read integer

187

text = mm[4:12].rstrip(b'!') # Read string

188

189

print(f"Value: {value}, Text: {text.decode()}")

190

191

# Clean up

192

mm.close()

193

shm.close_fd()

194

shm.unlink()

195

```

196

197

### Multi-Process Data Sharing

198

199

```python

200

import posix_ipc

201

import mmap

202

import os

203

import time

204

205

# Producer process

206

def producer():

207

# Create shared memory

208

shm = posix_ipc.SharedMemory('/data_shm', posix_ipc.O_CREAT, size=1024)

209

mm = mmap.mmap(shm.fd, shm.size)

210

211

# Write data periodically

212

for i in range(10):

213

data = f"Message {i}".encode()

214

mm[0:len(data)] = data

215

mm[len(data)] = 0 # Null terminator

216

time.sleep(1)

217

218

mm.close()

219

shm.close_fd()

220

# Don't unlink - consumer will do it

221

222

# Consumer process

223

def consumer():

224

# Open existing shared memory

225

try:

226

shm = posix_ipc.SharedMemory('/data_shm')

227

mm = mmap.mmap(shm.fd, shm.size)

228

229

# Read data

230

for i in range(10):

231

# Find null terminator

232

null_pos = mm.find(b'\x00')

233

if null_pos > 0:

234

data = mm[0:null_pos].decode()

235

print(f"Consumer read: {data}")

236

time.sleep(1)

237

238

mm.close()

239

shm.close_fd()

240

shm.unlink() # Consumer cleans up

241

242

except posix_ipc.ExistentialError:

243

print("Shared memory not found")

244

```

245

246

### Using with Different Size Operations

247

248

```python

249

import posix_ipc

250

import os

251

252

# Create segment with initial size

253

shm = posix_ipc.SharedMemory('/resizable_shm', posix_ipc.O_CREAT, size=512)

254

print(f"Initial size: {shm.size}")

255

256

# Resize using os.ftruncate() (alternative to size parameter)

257

os.ftruncate(shm.fd, 2048)

258

print(f"Resized to: {shm.size}")

259

260

# Note: On macOS, you can only call ftruncate() once per segment lifetime

261

262

shm.close_fd()

263

shm.unlink()

264

```

265

266

### Read-Only Access

267

268

```python

269

import posix_ipc

270

import mmap

271

272

# First process creates and writes data

273

shm_writer = posix_ipc.SharedMemory('/readonly_shm', posix_ipc.O_CREAT, size=1024)

274

mm_writer = mmap.mmap(shm_writer.fd, shm_writer.size)

275

mm_writer[0:12] = b'Hello World!'

276

mm_writer.close()

277

shm_writer.close_fd()

278

279

# Second process opens read-only

280

shm_reader = posix_ipc.SharedMemory('/readonly_shm', read_only=True)

281

mm_reader = mmap.mmap(shm_reader.fd, shm_reader.size, access=mmap.ACCESS_READ)

282

283

# Read data

284

data = mm_reader[0:12]

285

print(f"Read: {data.decode()}")

286

287

# Clean up

288

mm_reader.close()

289

shm_reader.close_fd()

290

posix_ipc.unlink_shared_memory('/readonly_shm')

291

```

292

293

### Error Handling

294

295

```python

296

import posix_ipc

297

298

try:

299

# Try to open non-existent shared memory

300

shm = posix_ipc.SharedMemory('/nonexistent')

301

except posix_ipc.ExistentialError:

302

print("Shared memory does not exist")

303

304

try:

305

# Try to create exclusive segment that already exists

306

shm1 = posix_ipc.SharedMemory('/existing', posix_ipc.O_CREAT)

307

shm2 = posix_ipc.SharedMemory('/existing', posix_ipc.O_CREX)

308

except posix_ipc.ExistentialError:

309

print("Shared memory already exists")

310

shm1.close_fd()

311

shm1.unlink()

312

313

try:

314

# Try to access segment without proper permissions

315

shm = posix_ipc.SharedMemory('/restricted', posix_ipc.O_CREAT, mode=0o000)

316

# Another process without permissions would get PermissionsError

317

except posix_ipc.PermissionsError:

318

print("Permission denied")

319

```