C 언어 에서 협정 실현 사례
협정 vs 라인
다 중 스 레 드 를 사용 하여 IO 차단 임 무 를 해결 하 는 것 보다 협 정 을 사용 하 는 장점 은 잠 금 을 추가 하지 않 고 공 유 된 데 이 터 를 방문 하여 동기 화 작업 을 하지 않 아 도 된다 는 것 이다.여기 서 설명 해 야 할 것 은 협 정 을 사용 할 때 자 물 쇠 를 추가 하지 않 아 도 되 는 이 유 는 모든 협 정 이 한 스 레 드 에서 만 운행 되 기 때 문 이 아니 라 협 정의 비 선점 식 특징 때문이다.협 정 을 사용 하면 CPU 를 자발적으로 내 놓 지 않 을 때 까지 다른 협 정 으로 갑자기 전환 되 지 않 는 다 는 것 이다.한편,스 레 드 는 선점 식 입 니 다.다 중 스 레 드 를 사용 하면 스 레 드 가 언제 운영 체제 에 의 해 배치 되 고 언제 전환 되 는 지 확인 할 수 없 기 때문에 잠 금 으로'원자 조작'을 실현 하 는 의미 가 필요 합 니 다.
협정 vs 비동기 반전
사실 더욱 일반적인 방법 은 차단 되 지 않 은 IO(예 를 들 어 비동기 IO,또는 syscall 에서 스스로 실현 하 는 비동기 IO,예 를 들 어 asio)를 사용 하고 처리 작업 을 반전 함수 에 쓰 는 것 이다.이런 방법 은 일반적으로 아무런 문제 가 없 지만,리 셋 함수 가 많아 지면 일 관 된 업무 코드 가 여러 리 셋 함수 로 나 뉘 어 유지 보수 의 원 가 를 증가 시 킬 것 이다.따라서 협 정 을 사용 하면 동기 화 된 쓰기 로 비동기 적 인 코드 를 쓸 수 있다.
static 변 수 를 이용 하여 협정 을 실현 하 다
하나의 협 정 을 실현 하려 면 함수 호출 의 문맥 을 어떻게 저장 하 느 냐 가 중요 하 다.이전에 인터넷 에서 블 로그coroutines in c를 보 았 는데 매우 간결 한 방식 으로 이 상하 문 저장 기능 을 실현 했다.구현 코드 는 다음 과 같 습 니 다:
#define crBegin static int _cr_state = 0; switch(_cr_state) { case 0:
#define crReturn(x) do { _cr_state = __LINE__; return x; case __LINE__:; } while (0)
#define crFinish }
int func1() {
crBegin
while (1)
{
printf("hello world
");
crReturn(0);
}
crFinish
}
이 코드 는 함수 의 static 변 수 를 이용 하여 함수 호출 상 태 를 저장 합 니 다.주의,vs 2013 디 버 깅 기능 이 있 기 때문에 vs 2013 의LINE__상수 가 아니 기 때문에 컴 파일 이 통과 되 지 않 고 gcc 를 사용 하면 컴 파일 할 수 있 습 니 다.이 코드 는 간단 하지만 문제 가 있 습 니 다.예 를 들 어 두 개의 협 정 이 같은 함 수 를 호출 하면 오류 가 발생 할 수 있 습 니 다.따라서 블 로그 에서 이 코드 를 언급 하 는 것 은 주로 하나의 방향 을 제시 하 는 것 이다.만약 에 실제 사용 하면 이렇게 하면 안 될 것 이다.setjmp,longjmp 를 이용 하여 협정 을 실현 하 다
앞에서 말 했 듯 이 협 정 을 실현 하 는 가장 중요 한 것 은 함수 호출 을 저장 하 는 문맥 이 고 이런 문맥 은 주로 두 부분 에 있 습 니 다.1.각 레지스터 의 값,2.함수 호출 스 택 입 니 다.C 언어 에 서 는 함수 호출 시 각 레지스터 의 값 을 setjmp 를 통 해 저장 할 수 있 습 니 다.저장 하면 longjmp 를 통 해 당초 setjmp 의 곳 으로 재현 할 수 있 습 니 다(크로스 함수 로 이해 할 수 있 는 goto).그러나 주의해 야 할 것 은 setjmp 는 레지스터 의 값 만 저장 하고 함수 호출 스 택 을 유지 하 는 것 은 책임 지지 않 습 니 다(이것 은 setjmp 의 jmp 를 보 세 요.buf 의 구 조 를 알 수 있 습 니 다)따라서 사용자 가 수 동 으로 이 함수 호출 스 택 을 유지 해 야 합 니 다.setjmp,longjmp 를 사용 하 는 흔 한 오 류 는 이미 실 행 된 함수 로 longjmp 를 시도 하 는 것 입 니 다.이때 레지스터 의 값 은 당시 에 저 장 된 값 이지 만 호출 스 택 은 원래 의 호출 스 택 이 아 닙 니 다.
제 방법 은 협 정 을 만 들 때 더미 위 에 공간(크기 2M)을 협 정의 호출 스 택 으로 신청 한 다음 에 setjmp 를 만 들 때 레지스터 esp 의 값 을 수 동 으로 변경 하여 제 가 만 든 호출 스 택 을 가리 키 는 것 입 니 다.그래서 앞으로 실 행 될 때 이 협 정 은 내 가 제공 한 메모 리 를 창고 로 사용 할 것 이다.
나의 이 협 정 고 는 세 개의 인 터 페 이 스 를 제공 했다.
그래서 문 제 는 많다.
물론 협 정 을 실현 하 는 데 더 좋 은 방법 도 있다.예 를 들 어 glibc 의 uontext 라 이브 러 리 를 사용 할 수 있다 면 이 라 이브 러 리 를 바탕 으로 이 루어 질 수 있 고 자신 이 수 동 으로 함수 호출 의 문맥 을 관리 하지 않 아 도 된다.예 를 들 어 구름 바람 이 실현 하 는 협 정 라 이브 러 리 와 같다.
여기 서 C 언어 에서 의 협상 실현 사례 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 C 언어 실현 협상 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C 언어 체인 시계는 뱀을 탐식하는 작은 게임을 실현한다본고의 실례는 여러분에게 C 언어 체인표가 뱀 탐식 게임을 실현하는 구체적인 코드를 공유하여 참고하도록 하였으며, 구체적인 내용은 다음과 같다. 프로젝트 이름: 뱀놀이 운영 환경: Linux 프로그래밍 언어: C 언...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.