or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

backend-context.mdcloudpickle-integration.mderror-handling.mdindex.mdprocess-pool-executor.mdreusable-executor.md

backend-context.mddocs/

0

# Backend Context

1

2

Loky's backend context management provides functions for configuring multiprocessing contexts, determining system resources, and managing process creation methods. These functions offer enhanced CPU detection and cross-platform compatibility.

3

4

## Capabilities

5

6

### CPU Count Detection

7

8

Enhanced CPU count function with support for physical cores and container awareness.

9

10

```python { .api }

11

def cpu_count(only_physical_cores=False):

12

"""

13

Return the number of CPUs available to the current process.

14

15

This implementation is CFS-aware (Linux Control Groups) and can distinguish

16

between logical and physical cores.

17

18

Parameters:

19

- only_physical_cores (bool): If True, return only physical cores.

20

If False, return logical cores. Default False.

21

22

Returns:

23

int: Number of available CPU cores

24

25

Note:

26

This function respects container limits, CPU affinity settings, and

27

cgroup constraints on Linux systems.

28

"""

29

```

30

31

### Context Management

32

33

Functions for managing multiprocessing contexts and start methods.

34

35

```python { .api }

36

def get_context(method=None):

37

"""

38

Get a multiprocessing context for the specified start method.

39

40

Parameters:

41

- method (str, optional): Start method name ('loky', 'spawn', 'fork', 'forkserver').

42

Defaults to 'loky' if not specified.

43

44

Returns:

45

LokyContext: Multiprocessing context for the specified method

46

47

Available methods:

48

- 'loky': Loky's enhanced context (default)

49

- 'loky_init_main': Special context for main process initialization

50

- 'spawn': Pure spawn context

51

- 'fork': Fork context (POSIX only, not recommended)

52

- 'forkserver': Fork server context (POSIX only)

53

"""

54

55

def set_start_method(method, force=False):

56

"""

57

Set the method for starting worker processes.

58

59

Parameters:

60

- method (str): Start method to use

61

- force (bool): Whether to force setting even if already set. Default False.

62

63

Returns:

64

None

65

66

Raises:

67

RuntimeError: If start method is already set and force=False

68

"""

69

70

def get_start_method():

71

"""

72

Get the current start method.

73

74

Returns:

75

str: Current start method name

76

"""

77

```

78

79

### Context Classes

80

81

Specialized context classes for different process creation strategies.

82

83

```python { .api }

84

class LokyContext:

85

"""Enhanced multiprocessing context with loky-specific features."""

86

def Process(self, *args, **kwargs): ...

87

def Queue(self, maxsize=0): ...

88

def SimpleQueue(self): ...

89

def Lock(self): ...

90

def RLock(self): ...

91

def Semaphore(self, value=1): ...

92

def BoundedSemaphore(self, value=1): ...

93

def Condition(self, lock=None): ...

94

def Event(self): ...

95

96

class LokyInitMainContext(LokyContext):

97

"""Context for main process initialization scenarios."""

98

```

99

100

## Usage Examples

101

102

### Basic CPU Count Usage

103

104

```python

105

from loky import cpu_count

106

107

# Get logical CPU count (includes hyperthreading)

108

logical_cpus = cpu_count()

109

print(f"Logical CPUs: {logical_cpus}")

110

111

# Get physical CPU count (excludes hyperthreading)

112

physical_cpus = cpu_count(only_physical_cores=True)

113

print(f"Physical CPUs: {physical_cpus}")

114

115

# Use for executor sizing

116

from loky import get_reusable_executor

117

executor = get_reusable_executor(max_workers=physical_cpus)

118

```

119

120

### Container-Aware CPU Detection

121

122

```python

123

from loky import cpu_count

124

125

# In containerized environments, cpu_count respects limits

126

available_cpus = cpu_count()

127

print(f"CPUs available to container: {available_cpus}")

128

129

# This is particularly useful in Docker containers with CPU limits

130

# where os.cpu_count() might return the host's CPU count

131

import os

132

host_cpus = os.cpu_count()

133

container_cpus = cpu_count()

134

135

print(f"Host CPUs: {host_cpus}")

136

print(f"Container CPUs: {container_cpus}")

137

```

138

139

### Context Configuration

140

141

```python

142

from loky.backend import get_context

143

from loky.backend.context import set_start_method, get_start_method

144

145

# Set the start method globally

146

set_start_method('loky')

147

148

# Get current start method

149

current_method = get_start_method()

150

print(f"Current start method: {current_method}")

151

152

# Get context for specific method

153

loky_context = get_context('loky')

154

spawn_context = get_context('spawn')

155

156

print(f"Loky context: {loky_context}")

157

print(f"Spawn context: {spawn_context}")

158

159

# Use context to create process-related objects

160

queue = loky_context.Queue()

161

lock = loky_context.Lock()

162

event = loky_context.Event()

163

```

164

165

### Custom Context Usage

166

167

```python

168

from loky import ProcessPoolExecutor

169

from loky.backend.context import get_context

170

171

def worker_function(x):

172

import os

173

return f"Process {os.getpid()}: {x * 2}"

174

175

# Use specific context

176

loky_context = get_context('loky')

177

178

# Create executor with custom context

179

executor = ProcessPoolExecutor(

180

max_workers=2,

181

context=loky_context

182

)

183

184

results = list(executor.map(worker_function, range(5)))

185

for result in results:

186

print(result)

187

188

executor.shutdown()

189

```

190

191

### Cross-Platform Start Method Selection

192

193

```python

194

import sys

195

from loky.backend.context import set_start_method, get_start_method

196

197

def configure_optimal_start_method():

198

"""Configure the best start method for the current platform."""

199

if sys.platform == 'win32':

200

# Windows only supports spawn

201

method = 'spawn'

202

else:

203

# Unix-like systems can use loky (recommended)

204

method = 'loky'

205

206

set_start_method(method, force=True)

207

return method

208

209

# Configure and display start method

210

method = configure_optimal_start_method()

211

current_method = get_start_method()

212

print(f"Configured start method: {method}")

213

print(f"Current start method: {current_method}")

214

```

215

216

### Advanced Context Features

217

218

```python

219

from loky.backend.context import get_context

220

221

# Get loky context with enhanced features

222

ctx = get_context('loky')

223

224

# Create synchronization primitives

225

lock = ctx.Lock()

226

rlock = ctx.RLock()

227

semaphore = ctx.Semaphore(2)

228

condition = ctx.Condition()

229

event = ctx.Event()

230

231

# Create queues

232

queue = ctx.Queue(maxsize=10)

233

simple_queue = ctx.SimpleQueue()

234

235

print("Created loky context objects:")

236

print(f"Lock: {lock}")

237

print(f"RLock: {rlock}")

238

print(f"Semaphore: {semaphore}")

239

print(f"Queue: {queue}")

240

print(f"SimpleQueue: {simple_queue}")

241

```

242

243

### Resource-Aware Executor Configuration

244

245

```python

246

from loky import get_reusable_executor, cpu_count

247

import psutil

248

249

def get_optimal_worker_count():

250

"""Determine optimal worker count based on system resources."""

251

# Get CPU information

252

physical_cores = cpu_count(only_physical_cores=True)

253

logical_cores = cpu_count(only_physical_cores=False)

254

255

# Get memory information (requires psutil)

256

try:

257

memory_gb = psutil.virtual_memory().total / (1024**3)

258

259

# Rule of thumb: 1 worker per 2GB RAM, but not more than physical cores

260

memory_workers = int(memory_gb / 2)

261

optimal_workers = min(physical_cores, memory_workers)

262

263

print(f"Physical cores: {physical_cores}")

264

print(f"Logical cores: {logical_cores}")

265

print(f"Memory: {memory_gb:.1f} GB")

266

print(f"Memory-based workers: {memory_workers}")

267

print(f"Optimal workers: {optimal_workers}")

268

269

return optimal_workers

270

except ImportError:

271

# Fallback if psutil not available

272

return physical_cores

273

274

# Configure executor with optimal worker count

275

optimal_workers = get_optimal_worker_count()

276

executor = get_reusable_executor(max_workers=optimal_workers)

277

```

278

279

### Context Method Comparison

280

281

```python

282

from loky.backend.context import get_context

283

import time

284

285

def timing_test(context_method, iterations=1000):

286

"""Test process creation speed for different context methods."""

287

ctx = get_context(context_method)

288

289

start_time = time.time()

290

291

processes = []

292

for _ in range(iterations):

293

# Create but don't start processes for timing

294

p = ctx.Process(target=lambda: None)

295

processes.append(p)

296

297

creation_time = time.time() - start_time

298

299

# Clean up

300

for p in processes:

301

del p

302

303

return creation_time

304

305

# Compare different context methods (on supported platforms)

306

methods = ['loky', 'spawn']

307

if sys.platform != 'win32':

308

methods.extend(['fork', 'forkserver'])

309

310

print("Process creation timing comparison:")

311

for method in methods:

312

try:

313

elapsed = timing_test(method, 100)

314

print(f"{method}: {elapsed:.4f} seconds")

315

except Exception as e:

316

print(f"{method}: Not available ({e})")

317

```

318

319

## Platform Considerations

320

321

### Windows

322

- Only 'spawn' and 'loky' methods available

323

- Maximum of ~60 workers on older Python versions

324

325

### Unix/Linux

326

- All start methods available ('loky', 'spawn', 'fork', 'forkserver')

327

- 'loky' recommended for robustness

328

- 'fork' not recommended due to thread safety issues

329

330

### Container Environments

331

- CPU count automatically respects container limits

332

- Works with Docker CPU constraints and Kubernetes resource limits

333

- Supports cgroup v1 and v2 CPU accounting