커 널 에서 어디서나 볼 수 있 는 대기 열 상세 설명 (회전)
/include/linux/wait.h
struct __wait_queue_head { spinlock_t lock; struct list_head task_list; }; typedef struct __wait_queue_head wait_queue_head_t;
2. 역할:
커 널 에 서 는 대기 열 을 기다 리 는 데 많은 도움 이 된다. 특히 중단 처리, 프로 세 스 동기 화, 정시 등 장소 에서.차단 프로 세 스 의 각성 을 위해 대기 열 을 사용 할 수 있 습 니 다.이 는 대기 열 을 바탕 으로 데이터 구 조 를 구축 하고 프로 세 스 스케줄 링 체제 와 밀접 하 게 결합 하여 커 널 의 비동기 이벤트 알림 체 제 를 실현 하고 시스템 자원 에 대한 접근 등 을 동기 화 할 수 있 습 니 다.
3. 필드 상세 설명:
1、spinlock_t lock;
tasklist 와 작업 과정 에서 이 자 물 쇠 를 사용 하여 대기 열 에 대한 상호 배척 접근 을 실현 합 니 다.
2、srtuct list_head_t task_list;
양 방향 순환 링크, 기다 리 는 프로 세 스 를 저장 합 니 다.
3. 조작:
1. 정의 및 초기 화:
(1)
wait_queue_head_t my_queue;
init_waitqueue_head(&my_queue);
직접 정의 하고 초기 화 합 니 다.init_waitqueue_head () 함 수 는 자 회전 자 물 쇠 를 잠 금 되 지 않 은 것 으로 초기 화하 고 대기 열 이 비어 있 는 양 방향 순환 링크 로 초기 화 합 니 다.
(2)
DECLARE_WAIT_QUEUE_HEAD(my_queue);
정의 하고 초기 화 합 니 다. (1) 에 해당 합 니 다.
(3) 대기 열 정의:
DECLARE_WAITQUEUE(name,tsk);
wait 를 정의 하 는 곳 입 니 다.queue_t 형식의 변수 name 을 private 와 tsk 로 설정 합 니 다.wait_queue_t 형식 정 의 는 다음 과 같 습 니 다.
struct __wait_queue { unsigned int flags; #define WQ_FLAG_EXCLUSIVE 0x01 void *private; wait_queue_func_t func; struct list_head task_list; };
이 중 flags 도 메 인 은 이 대기 프로 세 스 가 상호 배척 프로 세 스 인지, 비 상호 배척 프로 세 스 인지 알려 줍 니 다. 이 중 0 은 비 상호 배척 프로 세 스 이 고, WQ FLAG EXCLUSIVE (0x 01) 는 상호 배척 프로 세 스 입 니 다. 대기 열 (wait quue t) 과 대기 열 (wait quue head t) 의 차 이 는 대기 열 이 대기 열 헤 더 를 기다 리 는 구성원 입 니 다. 대기 열 헤 더 를 기다 리 는 task list 도 메 인 링크 의 구성원 은 대기 열 형식 입 니 다.(wait_queue_t)。
2. (대기 열 헤더 에서) 대기 열 추가 / 이동:
(1) add wait queue () 함수:
void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; wait->flags &= ~WQ_FLAG_EXCLUSIVE; spin_lock_irqsave(&q->lock, flags); __add_wait_queue(q, wait); spin_unlock_irqrestore(&q->lock, flags); }
기다 리 는 프로 세 스 를 서로 배척 하지 않 는 프로 세 스 로 설정 하고 대기 열 헤더 (q) 의 헤더 에 추가 합 니 다.
void fastcall add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; wait->flags |= WQ_FLAG_EXCLUSIVE; spin_lock_irqsave(&q->lock, flags); __add_wait_queue_tail(q, wait); spin_unlock_irqrestore(&q->lock, flags); }
이 함수 도 add wait queue () 함수 기능 과 기본적으로 같 습 니 다. 기다 리 는 프로 세 스 (wait) 를 상호 배척 프로 세 스 로 설정 할 뿐 입 니 다.
(2) remove wait queue () 함수:
void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; spin_lock_irqsave(&q->lock, flags); __remove_wait_queue(q, wait); spin_unlock_irqrestore(&q->lock, flags); }
기다 리 는 자원 이나 이벤트 가 만족 할 때 프로 세 스 가 깨 어 나 이 함 수 를 사용 하면 대기 머리 에서 삭 제 됩 니 다.
3. 이벤트 대기:
(1) wait event () 매크로:
#define wait_event(wq, condition) / do { / if (condition) / break; / __wait_event(wq, condition); / } while (0) #define __wait_event_timeout(wq, condition, ret) / do { / DEFINE_WAIT(__wait); / / for (;;) { / prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); / if (condition) / break; / ret = schedule_timeout(ret); / if (!ret) / break; / } / finish_wait(&wq, &__wait); / } while (0)
대기 열 에서 condition 이 진짜 일 때 까지 잠 을 자 십시오. 대기 하 는 동안 프로 세 스 는 TASK UNINTERRUPTIBLE 로 설정 되 어 condition 변수 가 진짜 로 변 할 때 까지 잠 을 잘 수 있 습 니 다. 프로 세 스 가 깨 어 날 때마다 condition 값 을 검사 합 니 다.
(2) wait event interruptible () 함수:
wait event () 와 의 차이 점 은 이 매크로 를 호출 하여 기다 리 는 동안 현재 프로 세 스 가 TASK INTERRUPTIBLE 상태 로 설 정 됩 니 다. 깨 어 날 때마다 condition 이 진짜 인지 확인 하고, 진짜 라면 되 돌아 갑 니 다. 그렇지 않 으 면 프로 세 스 가 신호 에 깨 어 났 을 때 - RESTARTSYS 오류 코드 로 돌아 갑 니 다. condition 이 진짜 라면 0 으로 돌아 갑 니 다.
(3) wait event timeout () 매크로:
wait event () 와 유사 합 니 다. 단, 주어진 수면 시간 이 마이너스 일 경우 즉시 돌아 갑 니 다. 수면 중 에 깨 어 나 면 condition 이 진짜 일 경우 남 은 수면 시간 으로 돌아 갑 니 다. 그렇지 않 으 면 주어진 수면 시간 에 도달 하거나 초과 할 때 까지 계속 잠 을 자고 0 으로 돌아 갑 니 다.
(4) wait event interruptible timeout () 매크로:
wait event timeout () 과 유사 하지만 수면 중 신호 가 끊 기 면 ERESTARTSYS 오류 코드 로 돌아 갑 니 다.
(5) wait event interruptible exclusive () 매크로
마찬가지 로 wait event interruptible () 과 같 지만 이 수면 의 프로 세 스 는 서로 배척 하 는 프로 세 스 입 니 다.
5 、 각성 대기 열:
(1) wake up () 함수:
#define wake_up(x) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, NULL) void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, void *key) { unsigned long flags; spin_lock_irqsave(&q->lock, flags); __wake_up_common(q, mode, nr_exclusive, 0, key); spin_unlock_irqrestore(&q->lock, flags); } static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int sync, void *key) { struct list_head *tmp, *next; list_for_each_safe(tmp, next, &q->task_list) { wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); unsigned flags = curr->flags; if (curr->func(curr, mode, sync, key) && (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) break; } }
대기 열 을 깨 웁 니 다. TASK INTERRUPTIBLE 과 TASK UNITERUPTIBLE 상태 에 있 는 프로 세 스 를 깨 우 고 wait event / wait event timeout 과 쌍 을 지어 사용 할 수 있 습 니 다.
(2) wake up interruptible () 함수:
#define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
wake up () 과 유일한 차이 점 은 TASK INTERRUPTIBLE 상태의 프로 세 스 만 깨 울 수 있다 는 것 입 니 다. wait event interruptible / wait event interruptible timeout / wait event interruptible exclusive 와 짝 을 지어 사용 합 니 다.
(3)
#define wake_up_all(x) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0, NULL) #define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL) #define wake_up_interruptible_all(x) __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
이것 도 기본적으로 wake up / wake up interruptible 과 같 습 니 다.
6. 대기 열 에서 잠 자기:
(1) sleep on () 함수:
void __sched sleep_on(wait_queue_head_t *q) {
unsigned long flags;
wait_queue_t wait; init_waitqueue_entry(&wait, current); current->state = TASK_UNINTERRUPTIBLE; sleep_on_head(q, &wait, &flags);
schedule();
sleep_on_tail(q, &wait, &flags);
}
이 함 수 는 대기 열 (wait) 을 정의 하고 현재 프로 세 스 를 대기 열 (wait) 에 추가 한 다음 현재 프로 세 스 의 상 태 를 TASK UNINTERRUPTIBLE 로 설정 하고 대기 열 (wait) 을 대기 열 헤더 (q) 에 추가 하 는 역할 을 합 니 다. 이후 자원 을 가 져 올 때 까지 대기 열 헤더 (q) 에서 걸 립 니 다.대기 열 헤더 에서 깨 웁 니 다. 대기 자원 이 걸 려 있 는 동안 이 프로 세 스 는 신호 로 깨 울 수 없습니다.
(2) sleep on timeout () 함수:
long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout)
{
unsigned long flags;
wait_queue_t wait
init_waitqueue_entry(&wait, current); current->state = TASK_UNINTERRUPTIBLE;
sleep_on_head(q, &wait, &flags);
timeout = schedule_timeout(timeout);
sleep_on_tail(q, &wait, &flags);
return timeout;
}
sleep on () 함수 와 의 차 이 는 이 함 수 를 호출 할 때 지 정 된 시간 내 에 (timeout) 대기 자원 을 얻 지 못 하면 되 돌아 오 는 것 입 니 다. 실제로 schedule timeout () 함 수 를 호출 하여 이 루어 집 니 다. 주의해 야 할 것 은 주어진 수면 시간 (timeout) 이 0 보다 적 으 면 잠 을 자지 않 습 니 다. 이 함 수 는 진정한 수면 시간 으로 돌아 갑 니 다.
(3) interruptible sleep on () 함수:
void __sched interruptible_sleep_on(wait_queue_head_t *q) { unsigned long flags; wait_queue_t wait; init_waitqueue_entry(&wait, current); current->state = TASK_INTERRUPTIBLE; sleep_on_head(q, &wait, &flags); schedule(); sleep_on_tail(q, &wait, &flags); }
이 함수 와 sleep on () 함수 의 유일한 차이 점 은 현재 프로 세 스 의 상 태 를 TASK INTERRUPTINLE 로 설정 하 는 것 입 니 다. 이 는 수면 중 에 이 프로 세 스 가 신 호 를 받 으 면 깨 어 난 다 는 것 을 의미 합 니 다.
(4) interruptible sleep on timeout () 함수:
long __sched interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) { unsigned long flags; wait_queue_t wait; init_waitqueue_entry(&wait, current); current->state = TASK_INTERRUPTIBLE; sleep_on_head(q, &wait, &flags); timeout = schedule_timeout(timeout); sleep_on_tail(q, &wait, &flags); return timeout; }
sleep on timeout () 함수 와 유사 합 니 다. 프로 세 스 는 수면 중 에 기다 리 는 시간 이 도착 하지 않 으 면 신호 에 의 해 깨 어 날 수도 있 고, 기다 리 는 시간 이 도착 해서 깨 어 날 수도 있 습 니 다.
이 네 가지 함 수 는 대기 열 에서 프로 세 스 를 잠 들 게 하 는 것 입 니 다. 작은 의아 함 에 불과 합 니 다. 실제 사용 하 는 과정 에서 필요 에 따라 적절 한 함 수 를 선택 하면 됩 니 다. 예 를 들 어 플 로 피 데이터 에 대한 읽 기와 쓰기 에서 장치 가 준비 되 지 않 으 면 sleep on () 함수 로 데 이 터 를 읽 을 수 있 을 때 까지 수면 을 취하 십시오.직렬 포트 를 열 때 직렬 포트 가 닫 힌 상태 에 있 으 면 interruptible sleep on () 함수 로 열 려 고 시도 합 니 다. 사 운 드 카드 드라이브 에서 사 운 드 데 이 터 를 읽 을 때 읽 을 수 있 는 데이터 가 없 으 면 읽 을 수 있 을 때 까지 충분 한 시간 을 기 다 립 니 다.
대기 열 애플 리 케 이 션 모드 대기 열 애플 리 케 이 션 은 두 프로 세 스 와 관련 되 어 있 습 니 다. A 와 B 로 가정 합 니 다. A 는 자원 의 소비자 이 고 B 는 자원 의 생산자 입 니 다. A 는 소비 할 때 자원 이 생산 되 었 는 지 확인 해 야 합 니 다. 이 대기 열 은 프로 세 스 A 와 프로 세 스 B 에 의 해 동시에 사용 되 어야 합 니 다. 전체 변수 로 정의 할 수 있 습 니 다. DECLARE WAIT QUEUE HEAD (rsc queue); 프로 세 스 A 에서 다음 과 같은 논 리 를 수행 합 니 다: while (resource is unavaiable) { interruptible sleep on (& wq);} consume resource (); 프로 세 스 B 에서 다음 과 같은 논 리 를 수행 합 니 다: produce resource (); wake up interruptible (& wq);
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.