Thread synchronization example

Basic idea with this example is to create several reader threads and two writer threads. When writer access synchronized block, it will block all other threads until it exits from that block. All reader threads can access synchronized block simultaneously as long as there is no writer.

Compilation

Easiest way to get this example running is to go to examples directory in package root, and run:

$ ./build.sh thread_sync

build.sh script compiles Ano script to C, copies source files in place and pops up instructions what to do next. Follow them. Check also examples/README for more info.

Preview

; ------------------------------------------------------------------------------
; thread_sync.ano
;
; To compile:
;
; $ ./build/ano ./examples/thread_sync/thread_sync.ano > \
;     engine/dsl_ano.h
; ------------------------------------------------------------------------------
;
@ANO_SCRIPT_NAME		thread_synchronizing
@ANO_SCRIPT_VERSION		0.0.1
@ANO_SCRIPT_DESCRIPTION	Simple thread synchronizing example
;
@ANO_FLAGS_USE_PROTOS		[ ]
@ANO_FLAGS_VAR_NAME_SUBS	[ ]
@ANO_FLAGS_VAR_WARN_UNUSED	[ ]
;
; Copyright © 2016-2026, Jani Salonen <salojan@goto10.co>
; All rights reserved.
;
; Basic idea with this example is to create several reader threads and two
; writer threads. When writer access synchronized block, it will block all
; other threads until it exits from that block. All reader threads can access
; synchronized block simultaneously as long as there is no writer.
;

main [exit: 0] {
	; Create writer thread.
	;
	thread_spawn (\
		thread_name: DEFAULT_THREAD, \
		thread_function: "my_writer")

	; Create reader threads.
	;
	for(mov _i (0); _i < 10; inc _i) {
		; Use loop counter as thread name.
		;
		mov _j (_i)
		ntos _j

		thread_spawn (\
			thread_name: _j, \
			thread_function: "my_reader")
	}

	; Create another writer thread.
	;
	thread_spawn (\
		thread_name: DEFAULT_THREAD, \
		thread_function: "my_writer")

	; Wait for all threads to complete.
	;
	thread_wait_all

	print "Threads done.\n"
}

thread my_reader (_id, _name) {
	print "Reader thread is starting…\n"

	; Get seconds to sleep.
	;
	rand _r (4)
	inc _r

	synchronized [role: reader, oid: 0] {
		print "This is synchronized block, reader is sleeping here" \
			" for " . _r . " seconds.\n"

		sleep (_r, 0)
	}

	print "…reader thread ends.\n"
}

thread my_writer (_id, _name) {
	print "Writer thread is starting…\n"

	; Get seconds to sleep.
	;
	rand _r (9)
	inc _r

	synchronized [role: writer, oid: 0] {
		print "This is synchronized block, writer is blocking other" \
			" threads and sleeping\nhere for " . _r . " seconds.\n"

		sleep (_r, 0)
	}

	print "…writer thread ends.\n"
}
; ------------------------------------------------------------------------------
; thread_sync.w2c
;
; To compile:
;
; $ ./build/widget ./examples/thread_sync/thread_sync.w2c > \
;     engine/widget_defs.h
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; thread_sync.m2c
;
; To compile:
;
; $ ./build/menu ./examples/thread_sync/thread_sync.m2c > \
;     engine/menu_defs.h
; ------------------------------------------------------------------------------

Copyright © 2026, Jani Salonen <salojan at goto10 piste co>. Piste is finnish word and means dot. All rights reserved.