Worker Pools in GDScript

Our example demonstrates how to implement a worker pool using threads and queues in GDScript.

extends Node

var jobs = []
var results = []
var num_jobs = 5
var num_workers = 3

func _ready():
    # Create the jobs
    for j in range(1, num_jobs + 1):
        jobs.append(j)
    
    # Start the workers
    for w in range(1, num_workers + 1):
        var thread = Thread.new()
        thread.start(self, "worker", w)
    
    # Wait for all jobs to complete
    while results.size() < num_jobs:
        OS.delay_msec(100)
    
    # Print results
    print("All jobs completed")

func worker(id):
    while not jobs.empty():
        var job = jobs.pop_front()
        if job != null:
            print("worker ", id, " started job ", job)
            OS.delay_msec(1000)  # Simulate an expensive task
            print("worker ", id, " finished job ", job)
            results.append(job * 2)

In this example, we’re using GDScript’s Thread class to create a pool of worker threads. Here’s how it works:

  1. We define the number of jobs and workers in the num_jobs and num_workers variables.

  2. In the _ready() function, which is called when the script is initialized:

    • We create the jobs and add them to the jobs array.
    • We start the worker threads using a for loop.
    • We wait for all jobs to complete by checking the size of the results array.
  3. The worker function is where each thread performs its work:

    • It continuously checks for jobs in the jobs array.
    • When it finds a job, it simulates work by waiting for a second using OS.delay_msec(1000).
    • After completing a job, it adds the result to the results array.

This implementation mimics the behavior of the original example, with some adaptations for GDScript:

  • Instead of channels, we use arrays (jobs and results) with thread-safe operations.
  • We use Thread.new() to create new threads, similar to goroutines.
  • OS.delay_msec() is used to simulate work, equivalent to time.Sleep().

When you run this script, you should see output similar to this:

worker 1 started job 1
worker 2 started job 2
worker 3 started job 3
worker 1 finished job 1
worker 1 started job 4
worker 2 finished job 2
worker 2 started job 5
worker 3 finished job 3
worker 1 finished job 4
worker 2 finished job 5
All jobs completed

Note that the exact order of execution may vary due to the nature of concurrent programming.

This example demonstrates how to implement a simple worker pool pattern in GDScript, allowing for concurrent execution of tasks.