패키지, 저장소 및 앱 카테고리 검색

패키지 상세v3.1.0

mutex

상호 배제 및 일반 및 읽기-쓰기 뮤텍스의 구현

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
34.8만
좋아요
117
Pub 점수
150

패키지 설치

flutter pub add mutex

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

mutex 패키지는 Dart용 상호 배제 메커니즘을 제공하며, 표준 및 읽기-쓰기 뮤텍스 구현이 포함되어 있습니다. 여러 개의 아일랜드 간에 공유 리소스에 안전하게 동시 접근할 수 있도록 하여 경쟁 조건을 방지합니다. 다중 스레드 환경에서 사용하도록 설계되었으며, 독점적 및 공유 잠금 기능을 모두 제공합니다. 비동기 애플리케이션에서 상태를 관리하는 데 이상적이며, 모바일, 웹, 데스크톱을 포함한 모든 주요 플랫폼을 지원합니다. 구현은 가볍고 Flutter 및 Dart의 동시성 모델과 원활하게 통합됩니다.

사용 사례

  • 격리된 환경에서 공유 데이터에 대한 액세스 동기화
  • 다중 격리 앱에서 핵심 섹션 보호
  • 고성능 데이터 액세스를 위한 읽기/쓰기 동시성 활성화
  • isolates 통신을 사용한 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.

카테고리

소스 저장소

이 패키지를 사용하는 프로젝트