搜尋套件、儲存庫與 APP 分類

套件詳情v3.1.0

mutex

互斥鎖,包含普通鎖和讀寫鎖的實現

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
34.8萬
喜歡數
117
Pub 分數
150

安裝套件

flutter pub add mutex

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

該 mutex 套件為 Dart 提供互斥機制,包含標準與讀寫鎖實作。它能確保在多個隔離環境中對共用資源進行安全的併發存取,避免競爭條件。此套件專為多執行緒環境設計,提供獨佔與共用鎖定功能。非常適合用於異步應用程式中的狀態管理,支援所有主要平台,包括行動裝置、Web 與桌面。其實現輕量,並與 Flutter 及 Dart 的併發模型無縫整合。

適用情境

  • 在隔離區中同步對共享資料的存取
  • 保護多隔離區應用程式中的關鍵部分
  • 啟用讀寫併發以實現高效能資料存取
  • 使用隔離通訊管理Flutter應用中的狀態
  • 實現執行緒安全的快取或佇列
  • 在背景任務中協調資源存取

主要特色

  • 用於獨佔存取的標準互斥鎖
  • 用於併發讀取的讀寫互斥鎖
  • 跨平台支援(Android、iOS、Web、macOS、Windows、Linux)
  • 輕量且高效之實作
  • 用於鎖取得與釋放的簡單 API
  • 跨隔離區的執行緒安全作業

適合對象

  • 開發並發 Dart/Flutter 應用的開發者
  • 需要隔離層級同步的應用程式
  • 高性能數據結構需要讀寫鎖
  • 必須避免競爭條件的系統
  • 使用隔離區進行並行處理的團隊

使用建議

  • 需要小心處理以避免死鎖
  • 不適用於單一隔離情境
  • 頻繁鎖爭用帶來的效能影響
  • 必須在隔離邊界內使用
  • 受限於 Dart 的隔離區模型,而非作業系統級線程
  • 鎖應盡快釋放,以防止阻塞

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

mutex

A library for creating locks to ensure mutual exclusion when running critical sections of code.

Purpose

Mutexes can be used to protect critical sections of code to prevent race conditions.

Although Dart uses a single thread of execution, race conditions can still occur when asynchronous operations are used inside critical sections. For example,

x = 42;
synchronousOperations(); // this does not modify x
assert(x == 42); // x will NOT have changed

y = 42; // a variable that other asynchronous code can modify
await asynchronousOperations(); // this does NOT modify y, but...
// There is NO GUARANTEE other async code didn't run and change it!
assert(y == 42 || y != 42); // WARNING: y might have changed

An example is when Dart is used to implement a server-side Web server that updates a database (assuming database transactions are not being used). The update involves querying the database, performing calculations on those retrieved values, and then updating the database with the result. You don't want the database to be changed by "something else" while performing the calculations, since the results you would write will not incorporate those other changes. That "something else" could be the same Web server handling another request in parallel.

This package provides a normal mutex and a read-write mutex.

Mutex

A mutex guarantees at most only one lock can exist at any one time.

If the lock has already been acquired, attempts to acquire another lock will be blocked until the lock has been released.

import 'package:mutex/mutex.dart';

...

final m = Mutex();

Acquiring the lock before running the critical section of code, and then releasing the lock.

await m.acquire();
// No other lock can be acquired until the lock is released

try {
  // critical section with asynchronous code
  await ...
} finally {
  m.release();
}
protect

The following code uses the protect convenience method to do the same thing as the above code. Use the convenence method whenever possible, since it ensures the lock will always be released.

await m.protect(() async {
  // critical section
});

If the critial section returns a Future to a value, the protect convenience method will return a Future to that value.

final result = await m.protect<int>(() async {
  // critical section
  return valueFromCriticalSection;
});
// result contains the valueFromCriticalSection

Read-write mutex

A read-write mutex allows multiple reads locks to be exist simultaneously, but at most only one write lock can exist at any one time. A write lock and any read locks cannot both exist together at the same time.

If there is one or more read locks, attempts to acquire a write lock will be blocked until all the read locks have been released. But attempts to acquire more read locks will not be blocked. If there is a write lock, attempts to acquire any lock (read or write) will be blocked until that write lock is released.

A read-write mutex can also be described as a single-writer mutex, multiple-reader mutex, or a reentrant lock.

import 'package:mutex/mutex.dart';

...

final m = ReadWriteMutex();

Acquiring a write lock:

await m.acquireWrite();
// No other locks (read or write) can be acquired until released

try {
  // critical write section with asynchronous code
  await ...
} finally {
  m.release();
}

Acquiring a read lock:

await m.acquireRead();
// No write lock can be acquired until all read locks are released,
// but additional read locks can be acquired.

try {
  // critical read section with asynchronous code
  await ...
} finally {
  m.release();
}
protectWrite and protectRead

The following code uses the protectWrite and protectRead convenience methods to do the same thing as the above code. Use the convenence method whenever possible, since it ensures the lock will always be released.

await m.protectWrite(() async {
  // critical write section
});

await m.protectRead(() async {
  // critical read section
});

If the critial section returns a Future to a value, these convenience methods will return a Future to that value.

final result1 await m.protectWrite<String>(() async {
  // critical write section
  return valueFromCritialSection1;
});
// result1 contains the valueFromCriticalSection1

final result2 = await m.protectRead(() async {
  // critical read section
  return valueFromCritialSection2;
});
// result2 contains the valueFromCriticalSection2

When mutual exclusion is not needed

The critical section should always contain some asynchronous code. If the critical section only contains synchronous code, there is no need to put it in a critical section. In Dart, synchronous code cannot be interrupted, so there is no need to protect it using mutual exclusion.

Also, if the critical section does not involve data or shared resources that can be accessed by other asynchronous code, it also does not need to be protected. For example, if it only uses local variables that other asynchronous code won't have access to: while the other asynchronous code could run, it won't be able to make unexpected changes to the local variables it can't access.

Features and bugs

Please file feature requests and bugs at the issue tracker.

所屬分類

原始碼儲存庫

使用此套件的專案