Part 1
요약·해설
Condition 자체와 waiting queue를 구분하고 signal 한 개와 broadcast 전체 wakeup을 설명합니다.
release · queue · reacquire
signal
broadcast
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
E0280F0FB96D521395AC0CA9077BC075DD8E3235AE5A02A0FD96D2A528FC9387
.. _condvar:
Condition Variables
###################
A :dfn:`condition variable` is a synchronization primitive
that enables threads to wait until a particular condition occurs.
.. contents::
:local:
:depth: 2
Concepts
********
Any number of condition variables can be defined (limited only by available RAM). Each
condition variable is referenced by its memory address.
To wait for a condition to become true, a thread can make use of a condition
variable.
A condition variable is basically a queue of threads that threads can put
themselves on when some state of execution (i.e., some condition) is not as
desired (by waiting on the condition). The function
:c:func:`k_condvar_wait` performs atomically the following steps;
#. Releases the last acquired mutex.
#. Puts the current thread in the condition variable queue.
Some other thread, when it changes said state, can then wake one (or more)
of those waiting threads and thus allow them to continue by signaling on
the condition using :c:func:`k_condvar_signal` or
:c:func:`k_condvar_broadcast` then it:
#. Re-acquires the mutex previously released.
#. Returns from :c:func:`k_condvar_wait`.
A condition variable must be initialized before it can be used.
Implementation
**************
Defining a Condition Variable
=============================
A condition variable is defined using a variable of type :c:struct:`k_condvar`.
It must then be initialized by calling :c:func:`k_condvar_init`.
The following code defines a condition variable:
.. code-block:: c
struct k_condvar my_condvar;
k_condvar_init(&my_condvar);
Alternatively, a condition variable can be defined and initialized at compile time
by calling :c:macro:`K_CONDVAR_DEFINE`.
The following code has the same effect as the code segment above.
.. code-block:: c
K_CONDVAR_DEFINE(my_condvar);
Waiting on a Condition Variable
===============================
A thread can wait on a condition by calling :c:func:`k_condvar_wait`.
The following code waits on the condition variable.
.. code-block:: c
K_MUTEX_DEFINE(mutex);
K_CONDVAR_DEFINE(condvar)
int main(void)
{
k_mutex_lock(&mutex, K_FOREVER);
/* block this thread until another thread signals cond. While
* blocked, the mutex is released, then re-acquired before this
* thread is woken up and the call returns.
*/
k_condvar_wait(&condvar, &mutex, K_FOREVER);
...
k_mutex_unlock(&mutex);
}
Signaling a Condition Variable
===============================
A condition variable is signaled on by calling :c:func:`k_condvar_signal` for
one thread or by calling :c:func:`k_condvar_broadcast` for multiple threads.
The following code builds on the example above.
.. code-block:: c
void worker_thread(void)
{
k_mutex_lock(&mutex, K_FOREVER);
/*
* Do some work and fulfill the condition
*/
...
...
k_condvar_signal(&condvar);
k_mutex_unlock(&mutex);
}
Suggested Uses
**************
Use condition variables with a mutex to signal changing states (conditions) from
one thread to another thread.
Condition variables are not the condition itself and they are not events.
The condition is contained in the surrounding programming logic.
Mutexes alone are not designed for use as a notification/synchronization
mechanism. They are meant to provide mutually exclusive access to a shared
resource only.
Configuration Options
*********************
Related configuration options:
* None.
API Reference
**************
.. doxygengroup:: condvar_apis
Part 3
한국어 전문 번역
Condition variable은 특정 condition이 생길 때까지 thread가 기다릴 수 있게 하는 synchronization primitive입니다. Available RAM 범위에서 필요한 수만큼 정의하고 memory address로 참조합니다.
개념
Condition variable은 실행 state가 원하는 상태가 아닐 때 thread가 자신을 넣는 waiting queue입니다. k_condvar_wait()은 마지막으로 획득한 mutex를 release하고 current thread를 condition-variable queue에 넣는 두 단계를 atomic하게 수행합니다.
다른 thread가 state를 바꾼 뒤 k_condvar_signal()로 하나 또는 k_condvar_broadcast()로 여러 waiting thread를 깨웁니다. 깨어나는 thread는 앞서 release한 mutex를 다시 획득한 뒤 k_condvar_wait()에서 반환합니다. 사용 전 반드시 초기화해야 합니다.
구현
Condition variable 정의
k_condvar type variable을 선언하고 k_condvar_init()으로 초기화합니다.
struct k_condvar my_condvar;
k_condvar_init(&my_condvar);K_CONDVAR_DEFINE()를 사용하면 compile time에 정의와 초기화를 함께 수행합니다.
K_CONDVAR_DEFINE(my_condvar);Condition variable 대기
Thread는 k_condvar_wait()으로 condition을 기다립니다. Block되는 동안 mutex를 release하고 wakeup 직전 다시 획득합니다.
K_MUTEX_DEFINE(mutex);
K_CONDVAR_DEFINE(condvar)
int main(void)
{
k_mutex_lock(&mutex, K_FOREVER);
/* block this thread until another thread signals cond. While
* blocked, the mutex is released, then re-acquired before this
* thread is woken up and the call returns.
*/
k_condvar_wait(&condvar, &mutex, K_FOREVER);
...
k_mutex_unlock(&mutex);
}Condition variable signal
k_condvar_signal()은 한 thread를, k_condvar_broadcast()는 여러 thread를 깨웁니다. 다음 worker는 mutex를 잠그고 condition을 충족한 뒤 signal합니다.
void worker_thread(void)
{
k_mutex_lock(&mutex, K_FOREVER);
/*
* Do some work and fulfill the condition
*/
...
...
k_condvar_signal(&condvar);
k_mutex_unlock(&mutex);
}권장 용도
Mutex와 condition variable을 함께 사용해 한 thread의 state change를 다른 thread에 알립니다. Condition variable 자체가 condition인 것은 아니며 event도 아닙니다. 실제 condition은 surrounding program logic에 있습니다.
설정 옵션
관련 configuration option은 없습니다.
API 참고: condvar_apis
다른 module에서 static condition variable을 참조하는 declaration입니다.
extern struct k_condvar <name>;K_CONDVAR_DEFINE(name)Condition variable을 static하게 정의하고 초기화합니다. 다른 module에서는 extern struct k_condvar
으로 접근할 수 있습니다. 매개변수
name: condition variable 이름
k_condvar_init(condvar)Condition variable을 초기화합니다.
매개변수
condvar: k_condvar structure pointer
반환값
0: condition variable 생성 성공
k_condvar_signal(condvar)Condition variable에서 대기 중인 thread 하나를 signal합니다.
매개변수
condvar: k_condvar structure pointer
반환값
0: 성공
k_condvar_broadcast(condvar)Condition variable에서 대기 중인 모든 thread를 unblock합니다.
매개변수
condvar: k_condvar structure pointer
반환값
integer: 성공 시 wakeup한 thread 수
k_condvar_wait(condvar, mutex, timeout)현재 소유한 mutex를 atomic하게 해제하고 condition variable에서 current thread를 block한 뒤, 같은 condition variable에 signal 또는 broadcast가 오면 mutex를 다시 획득하고 반환합니다.
매개변수
condvar: k_condvar structure pointermutex: mutex 주소timeout: 대기 시간 또는 K_NO_WAIT/K_FOREVER
반환값
0: 성공-EAGAIN: 대기 시간 만료
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.