링크 ux 에서 sleep 상세 설명 및 간단 한 인 스 턴 스 실현

5807 단어 linuxsleep
링크 ux 에서 sleep 상세 설명 및 간단 한 인 스 턴 스 실현
sleep:
일반 버 전
1.기본 적 인 디자인 방향:
   1>SIGALRM 신호 처리 함수 등록 하기;
   2>알 람(nsecs)을 호출 하여 알 람 설정 하기;
   3>스토리 보드 pause 대기,커 널 을 다른 프로 세 스 로 전환 하여 실행 합 니 다.
   4>nsecs 초 후 알 람 이 시간 을 초과 하여 커 널 에서 SIGALRM 을 보 냅 니 다.
   5>커 널 상태 에서 이 프로 세 스 의 스토리 보드 상태 로 돌아 가기 전에 미결 신 호 를 처리 한 결과 SIGALRM 신호 가 있 는 것 을 발 견 했 습 니 다.그 처리 함 수 는 sig 입 니 다.alrm;
   6>사용자 상태 로 전환 하여 sig 실행alrm 함수,입⼊sigalrm 함수 시 SIGALRM 신호 가 움 직 이면 sig 에서 차 단 됩 니 다.alrm 함 수 는 SIGALRM 신 호 를 되 돌려 줍 니 다.그 다음 에 12163 실 행 됩 니 다.시스템 은 sigreturn 을 호출 하여 다시 커 널 에 들 어간 다음 에 사용자 상태 로 돌아 가 프로 세 스 의 주 제어 프로 세 스(main 함수 가 스토리 보드 의 my sleep 함수)를 계속 실행 합 니 다.
   7>pause 함수 반환-1,그리고 스토리 보드 알 람(0)을 옮 겨 알 람 을 취소 하고,스토리 보드 sigaction 을 옮 겨 SIGALRM 신호 이전의 처리 동작 을 복원 합 니 다.
2.실현 코드

#include<stdio.h> 
#include<signal.h> 
 
void handler(int signo) 
{} 
 
int mysleep(int timeout) 
{ 
  struct sigaction act,oact; 
  act.sa_handler = handler; 
  act.sa_flags = 0; 
  sigemptyset(&act.sa_mask); 
 
  sigaction(SIGALRM,&act,&oact); 
  alarm(timeout); 
  pause(); 
  int ret = alarm(0); 
  sigaction(SIGALRM,&oact,NULL); 
  return ret; 
} 
 
int main() 
{ 
  while(1) 
  { 
    printf("using musleep!
"); mysleep(3); } return 0; }
관련 함수 분석:

#include <unistd.h> 
int pause(void); 
pause 함 수 는 신호 가 전 달 될 때 까지 스토리 보드 프로 세 스 를 연결 합 니 다.만약 에 신호 처리 동작 이 끝 이 12108 프로 세 스 라면 프로 세 스 가 끝 이 12108 입 니 다.pause 함수 가 돌아 올 기회 가 없습니다.신호 처리 동작 이 무시 되면 프로 세 스 가 계속 걸 려 있 고 pause 는 돌아 오지 않 습 니 다.신호 처리 동작 이 캡 처 라면 신호 처리 함 수 를 옮 긴 후 pause 를 되 돌려 줍 니 다.-1,errno 는 EINTR 로 설정 되 어 있 기 때문에 pause 는 잘못된 반환 값 만 있 습 니 다.
sigaction 함수

#include <signal.h> 
int sigaction(int signo, const struct sigaction *act, struct 
sigaction *oact); 
sigaction 함 수 는 지정 한 신호 와 연 결 된 처리 동작 을 읽 고 수정 할 수 있 습 니 다.스토리 보드 가 성공 하면 0 으로 돌아 가 고,오류 가 발생 하면 되 돌아 갑 니 다-1.signo 는 지 정 된 신호 의 번호 입 니 다.act 포인터 가 비어 있 으 면 act 에 따라 이 신호 처리 동작 을 수정 합 니 다.oact 포인터 가 비어 있 지 않 으 면 oact 를 통 해 원래 의 처리 동작 을 전달 합 니 다. 

int sigemptyset(sigset_t *set); 
함수 sigemptyset 은 set 가 가리 키 는 신호 집합 을 초기 화하 여 모든 신호 에 대응 하 는 bit 를 제거 합 니 다.표 는 12144 입 니 다.이 신호 집합 은 효과 적 인 신 호 를 포함 하지 않 습 니 다.
2.최적화 버 전
필요 함수 분석

#include <signal.h>
 
int sigsuspend(const sigset_t *sigmask); 
siguspend 는 값 을 성공 적 으로 되 돌려 주지 못 했 습 니 다.전체 12175°신호 처리 함 수 를 집 은 후에 siguspend 가 되 돌아 갑 니 다.반환 값 은-1 이 고 errno 는 EINTR 로 설정 합 니 다.스토리 보드 siguspend 를 조정 할 때 프로 세 스 의 신호 차단 자 는 sigmask 매개 변수 로 지정 되 어 있 습 니 다.sigmask 가 올 때 특정한 신호 에 대한 차단 을 해제 하고 기 다 립 니 다.siguspend 가 돌아 올 때 프로 세 스 의 신호 차단 자 는 원래 의 값 으로 복원 할 수 있 습 니 다.이 신호 가 차단 되 어 있 으 면 siguspend 가 돌아 온 후에 도 차단 되 어 있 습 니 다.
siguspend 함수 와 pause 함수:프로그램 을 걸 수 있 지만 siguspend 함 수 는 신호 차단 자 를 해제 하고 걸 수 있 습 니 다.
sigprocmask
스토리 보드 함수 sigprocmask 를 사용 하면 프로 세 스 의 신호 차단 자 를 읽 거나 변경 할 수 있 습 니 다(차단 신호 집합).

#include <signal.h>
 
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 
oset 가 빈 포인터 라면 프로 세 스 의 현재 신호 차단 자 를 읽 고 oset 매개 변 수 를 통 해 전달 합 니 다.set 가 빈 포인터 라면 프로 세 스 의 신호 차단 자 를 변경 합 니 다.매개 변수 how 는 어떻게 변경 합 니까?oset 와 set 가 모두 12206°빈 포인터 라면 원래 의 신호 차단 자 를 oset*12197°로 백업 한 다음 set 와 how 매개 변수 에 따라 신호 차단 자 를 변경 합 니 다.
how 옵션 의미

만약 에 sigprocmask 를 옮 겨 서 현재 해결 되 지 않 은 신호 에 대한 차단 을 해제 하면 sigprocmask 가 돌아 오기 전에 그 중에서 12032 개의 신 호 를 적 게 전달 합 니 다.
코드 구현:

#include<stdio.h> 
#include<signal.h> 
 
void handler(int signo) 
{} 
 
int mysleep(int timout) 
{ 
  struct sigaction act,oact; 
  sigset_t newmask,oldmask,suspmask; 
  act.sa_handler = handler; 
  act.sa_flags = 0; 
  sigemptyset(&act.sa_mask); 
 
  sigaction(SIGALRM,&act,&oact); 
  sigemptyset(&newmask); 
  sigaddset(&newmask,SIGALRM); 
  sigprocmask(SIG_BLOCK,&newmask,&oldmask); 
 
  alarm(timout); 
 
  suspmask = oldmask; 
  sigdelset(&suspmask,SIGALRM); 
  sigsuspend(&suspmask); 
   
  int unslept = alarm(0); 
  sigaction(SIGALRM,&oact,NULL); 
  sigprocmask(SIG_SETMASK,&oldmask,NULL); 
  return(unslept); 
} 
int main() 
{ 
  while(1) 
  { 
    printf("using musleep!
"); mysleep(3); } return 0; }
최적화 버 전 은 일반 버 전에 존재 하 는 경쟁 문 제 를 해결 했다.우 리 는 일반 버 전의 순서 문 제 를 다시 한번 살 펴 보 자.
1.SIGALRM 신호 의 처리 함 수 를 설정 합 니 다.
2.알 람()함수 로 알 람 설정 하기;
3.커 널 은 현재 프로 세 스 를 대체 하기 위해 더 높 은 우선 순위 의 프로 세 스 를 선택 하고 이러한 프로 세 스 가 많 으 며 실행 시간 도 길다.
4.알 람 시간 이 초과 되 었 습 니 다.커 널 은 SIGALRM 신 호 를 이 프로 세 스에 보 내 고 미결 상태 에 있 습 니 다.
5.우선 순위 가 높 은 프로 세 스 가 끝 난 후에 커 널 은 이 프로 세 스 를 되 돌려 야 합 니 다.SIGALRM 신호 전달,집⾏처리 함수 sigalrm 이후 다시 커 널 로 들 어 갑 니 다.
6.이 프로 세 스 의 주 제어 프로 세 스 를 되 돌려 줍 니 다.alarm(nsecs)을 되 돌려 주 고,스토리 보드 pause()를 걸 어 놓 고 기 다 립 니 다.
7.그러나 현재 SIGALRM 신 호 는 처리 되 었 고 프로 세 스 가 오 류 를 초래 할 수 있 습 니 다.
프로 세 스 가 실행 되 는 과정 에서 비동기 로 인해 다른 우선 순위 가 높 은 프로 세 스 에 의 해 순서 문제 로 인 한 오류 가 발생 할 수 있 습 니 다.이런 문 제 를 경쟁 문제 라 고 한다.
최적화 버 전에 서 는 먼저 SIGALRM 신호 처리 함 수 를 설정 한 다음 SIGALRM 신 호 를 차단 한 다음 에 alarm()함수 로 알 람 을 설정 한 다음 에 sigprocmask()함 수 를 호출 하여 SIGALRM 신호 에 대한 차단 을 해제 한 다음 에 끊 고 기 다 려 서 경쟁 문 제 를 해결 했다.
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기