semaphore 실현 메커니즘

4812 단어 Semaphore
관련 데이터 구 조 는 먼저 신 호 량 과 관련 된 데이터 구 조 를 살 펴 보 자. < include / linux / semaphore. h > struct semaphore {spinlock t lock; \ # lock 은 이 신 호 량 의 자 회전 자물쇠 unsigned int count 일 것 이다. \ # count 는 이 신 호 량 의 카운터 struct list head wait list 를 나타 낸다. \ # wait list 는 말 그대로 링크 를 기다 리 는 것 일 것 이다.}신 호 량 의 데이터 구 조 는 이렇게 간단 합 니 다. 그러면 신 호 량 의 초기 화 는 어떻게 하 는 것 입 니까?그리고 여러분 이 잘 아 는 신 호 량 P, V 조작 은 어떻게 이 루어 집 니까?신 호 량 초기 화: \ # define DECLAREMUTEX(name) \ struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1) #define __SEMAPHORE_INITIALIZER (name, n) \ {\. lock = SPIN LOCK UNLOCKED (name). lock), \ \ # 자선 자물쇠. count = n, \ \ # 신 호 량 계수 기 를 n 으로 할당 합 니 다. wait list = LIST HEAD INIT ((name). wait list), \ \ # 대기 열 초기 화} 도 다음 방법 으로 신 호 량 을 초기 화 할 수 있 습 니 다: static inline void semainit(struct semaphore *sem, int val) { static struct lock_class_key __key; *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); } #define init_MUTEX(sem) sema_init(sem, 1) #define init_MUTEX_LOCKED(sem) sema_init (sem, 0) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------\ # 링크 가 비어 있 으 면 이 신 호 량 을 기다 리 고 있 는 프로 세 스 가 없다 는 뜻 입 니 다. count + 를 기다 리 면 sem - > count +, else up (sem), spin unlock irqrestore (& sem - > lock, flags),} 링크 가 비어 있 으 면 이 신 호 량 을 기다 리 고 있 는 프로 세 스 가 없다 는 뜻 입 니 다. count + 를 기다 리 면 됩 니 다. 링크 가 비어 있 지 않 으 면 이 신 호 량 을 기다 리 는 프로 세 스 가 있 습 니 다.up () 이 함수 중: < kernel / semaphore. c > static noinline voidsched __up (struct semaphore * sem) {\ # 대기 링크 의 맨 앞 에 있 는 프로 세 스 struct semaphore waiter * waiter = list first entry (& sem - > wait list, struct semaphore waiter, list) 꺼 내기; list del (& waiter - > list); \ # 이 프로 세 스 를 대기 링크 에서 waiter - > up = 1; wake up process (waiter - > task); \ # 이 프로 세 스 를 깨 웁 니 다}이 함 수 는 대기 목록 에서 맨 앞 에 있 는 프로 세 스 를 꺼 내 서 < kernel / semaphore. c > struct semaphore 깨 웁 니 다.waiter {struct list head list; \ # 링크 항목 struct task struct * task; \ # 프로 세 스 구조, 프로 세 스 PCB int up 이 라 고도 할 수 있 습 니 다.};이 구 조 는 주로 프로 세 스 를 신 호 량 의 대기 열 에 두 는 것 을 보조 하 는 데 사 용 됩 니 다. 뒤의 V 작업 은 그것 을 다시 소개 합 니 다.; \ # sem 을 조작 하려 면 잠 금 if (likely (sem - > count > 0) 를 추가 합 니 다. \ # count > 0 이면 바로 count -- 하면 됩 니 다. sem - > count --; else down (sem); \ # 호출 down () spin unlock irqrestore (& sem - > lock, flags); \ # sem 작업 이 끝나 면 잠 금 해제} count 가 < = 0 이면 호출down () 대기 열 에 프로 세 스 를 넣 습 니 다. 지금 보 세 요down () 이 어떻게 이 루어 졌 는 지 < kernel / semaphore. c > static noinline voidsched __down(struct semaphore *sem) { __down_common(sem, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); } static inline int __sched __down_common (struct semaphore * sem, long state, long timeout) {struct task struct * task = current; \ # 현재 실행 중인 프로 세 스 struct semaphore waiter waiter; list add tail (& waiter. list, & sem - > wait list); \ # waiter 를 링크 sem - > wait list 뒤에 waiter. task = task; \ # waiter 의 task 를 실행 중인 이 프로 세 스 waiter. up = 0; for (;) 로 설정 합 니 다.{if (signal pending state (state, task)) \ # 프로 세 스 가 예상 치 못 한 신호 에 중단 되면 대기 (대기 링크 에서 삭제) 를 포기 하고 - INTR 오류 번호 goto interrupted 로 돌아 갑 니 다. if (timeout < = 0) \ # 대기 시간 이 되면 대기 링크 에서 삭제 하고 - ETIME 오류 번호 goto timed out 로 돌아 갑 니 다. set task state (task, state); \ # 프로 세 스 상 태 를 TASK UNINTERRUPTIBLE spin unlock irq (& sem - > lock) 로 설정 합 니 다. timeout = schedule timeout (timeout); \ # 调度 spin lock irq (& sem - > lock); if (waiter. up) return 0;} timed out: list del (& waiter. list); return - ETIME; interrupted: list del (& waiter. list); return - INTR;}이 함 수 는 먼저 semaphore waiter 구 조 를 신청 합 니 다. < kernel / semaphore. c > struct semaphore waiter {struct list head list; struct task struct * task; int up;}; 그리고 이 구 조 를 sem 신 호 량 의 대기 링크 sem - > wait list 에 추가 한 다음 현재 프로 세 스 task 를 waiter. task 에 입력 한 다음 한 순환 에서 프로 세 스 스케줄 링 schedule timeout 을 진행 합 니 다 스케줄 링.timeout 는 현재 프로 세 스 task 의 상태 가 준비 되면 interrupt 으로 이동 합 니 다. 신 호 량 목록 sem - > wait list 에서 이 작업 에 대응 하 는 노드 를 삭제 합 니 다. 의외 의 신호 나 대기 시간 에 부 딪 히 면 신 호 량 목록 sem - > wait list 에서 해당 하 는 노드 를 삭제 하고 해당 하 는 오류 번호 로 돌아 갑 니 다.기타 V 조작 내 핵 은 또 다른 몇 가지 V 조작 을 제공 했다. static noinline int down interruptible (struct semaphore * sem), static noinline int down killable (struct semaphore * sem), static noinline int down timeout (struct semaphore * sem, long jiffies)여기 서 일일이 소개 하지 않 겠 습 니 다. 관심 있 는 학 우 는 연구 하 러 갈 수 있 습 니 다.
sem_open,sem_wait,sem_post,sem_unlink

좋은 웹페이지 즐겨찾기