std.sync

Function Description

The sync package provides concurrent programming capabilities.

As more computers begin to use multi-core processors, concurrent programming becomes more important to give full play to the advantages of multi-core processors.

Different programming languages implement threads in different ways. In some programming languages, threads are created by calling an operating system (OS) API. In this case, each language thread corresponds to an OS thread, which is generally referred to as a 1:1 thread model. Some other programming languages provide a special thread implementation, which allows multiple language threads to be switched and executed in contexts of different quantities of OS threads. This implementation is also referred to as an M:N thread model. Specifically, M language threads are scheduled and executed on N OS threads, where M and N may not be equal.

The Cangjie programming language is intended to provide a user-friendly, efficient, and unified concurrent programming interface so that you do not need to care about the differences between concepts such as OS threads and user-mode threads. In addition, details of the underlying implementation are concealed. Therefore, we provide only the concept of Cangjie thread. The Cangjie thread is implemented using the M:N thread model. Therefore, it is essentially a user-mode lightweight thread that supports preemption and occupies less memory resources than the OS thread.

To execute a section of code concurrently, you only need to create one Cangjie thread.

To create a new Cangjie thread, you can use the keyword spawn and pass a lambda expression without formal parameters. The lambda expression is the code expected to be executed in the new thread.

Examples:

Create a Cangjie thread using the keyword spawn:


main () {
    spawn {
        // Executed in the new thread
        println("Thread: ${Thread.currentThread.id}")
    }
    // Executed in the main thread
    println("Thread: ${Thread.currentThread.id}")
    sleep(Duration.second)

    0
}

The sync package provides different types of atomic operations, reentrant mutex and APIs thereof, and uses thread synchronization mechanism of shared variables and timers.

Atomic operations include operations of the integer type, Bool type, and reference type.

The integer types include Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, and UInt64.

Atomic operations of the integer type include basic operations such as read (load) and write (store), swap (swap/compareAndSwap), and arithmetic operation (fetchAdd/fetchSub). Note the following:

  • The returns of the swap operation and arithmetic operation are values not modified.

  • compareAndSwap is used to check whether the value of the current atomic variable is equal to the specified value. If they are equal, the value is replaced with another value. If they are not equal, the value is not replaced.

Atomic operations of the Bool type and reference type provide only read, write, and swap operations. Note the following:

The atomic operations of the reference type are valid only for the reference type.

Lock has many drawbacks in application. For example, you may forget to unlock, or when the mutex is held, an exception of being unable to automatically release the lock, is thrown. Therefore, the Cangjie programming language provides the keyword synchronized for solving similar problems in combination with Lock.

A mutex instance is added after synchronized to protect the subsequent modified code block. In this way, only one thread can execute the protected code at any time.

  • Before entering a code block modified by synchronized, a thread automatically acquires a lock corresponding to the Lock instance. If failing to acquire the lock, the current thread is blocked.
  • Before exiting the code block modified by synchronized (including use of control transfer expressions such as break, continue, return, and throw in the code block), a thread automatically releases the lock of the Lock instance.

Examples:

Before entering the synchronized code block, the thread of each for loop automatically acquires a lock corresponding to the mtx instance. Before exiting the code block, the thread releases the lock corresponding to the mtx instance.

import std.sync.Mutex

main () {
    let mtx = Mutex()
    let cnt = Box<Int64>(0)

    for (_ in 0..10) {
        spawn {
            synchronized(mtx) {
                cnt.value ++
                println("count: ${cnt.value}")
            }
        }
    }

    sleep(Duration.second)
    0
}

API List

Constant & Variable

NameDescription
DefaultMemoryOrder (deprecated)Specifies the default memory order. For details, see MemoryOrder (deprecated).

Interface

NameDescription
ConditionProvides an interface that can block a thread and wait for a signal from another thread to resume execution.
IReentrantMutex (deprecated)Provides an interface for reentrant mutexes.
LockProvides an interface for implementing reentrant mutexes.
UniqueLockProvides an interface for implementing exclusive locks.

Class

NameDescription
AtomicBoolProvides functions related to atomic operations of the Bool type.
AtomicInt16Provides functions related to atomic operations of the Int16 type.
AtomicInt32Provides functions related to atomic operations of the Int32 type.
AtomicInt64Provides functions related to atomic operations of the Int64 type.
AtomicInt8Provides functions related to atomic operations of the Int8 type.
AtomicOptionReferenceProvides functions related to atomic operations of the reference type.
AtomicReferenceProvides functions related to atomic operations of the reference type.
AtomicUInt16Provides functions related to atomic operations of the UInt16 type.
AtomicUInt32Provides functions related to atomic operations of the UInt32 type.
AtomicUInt64Provides functions related to atomic operations of the UInt64 type.
AtomicUInt8Provides functions related to atomic operations of the UInt8 type.
BarrierCoordinates multiple threads to stop at a point of a program.
Monitor (deprecated)Provides functions for blocking a thread and waiting for a signal from another thread to resume execution.
MultiConditionMonitor (deprecated)Provides functions for binding multiple condition variables to a mutex.
MutexProvides functions related to reentrant locks.
ReadWriteLockProvides functions related to the reentrant read/write lock.
ReentrantMutex (deprecated)Provides functions related to reentrant locks.
ReentrantReadMutex (deprecated)Provides the read lock type of the reentrant read/write lock.
ReentrantReadWriteMutex (deprecated)Provides functions related to the reentrant read/write lock.
ReentrantWriteMutex (deprecated)Provides the write lock type of the reentrant read/write lock.
SemaphoreProvides semaphore-related functionality.
SyncCounterProvides the countdown counter functionality.
TimerProvides the timer functionality.

Enumeration

TypeDescription
MemoryOrder (deprecated)Enumerates memory order types.
ReadWriteMutexMode (deprecated)Enumerates the read/write lock fairness modes.
CatchupStyleEnumerates the catch-up policies used by a repetitive task timer.

Struct

NameDescription
ConditionID (deprecated)Specifies the condition variable of a mutex. For details, see MultiConditionMonitor.

Exception Class

NameDescription
IllegalSynchronizationStateExceptionIndicates an invalid synchronization state.