>  기사  >  Java  >  평균? 더 많은 맥락을 제공해 주세요.

평균? 더 많은 맥락을 제공해 주세요.

王林
王林앞으로
2023-05-08 22:16:291359검색

1 프로세스 개요

프로세스는 운영 체제 서적에서 프로세스에 대해 많이 이해하고 있지만 프로세스 구현에 대해서는 잘 알지 못할 수도 있습니다.
프로세스의 구현은 실제로 우리가 일반적으로 코드를 작성할 때와 동일합니다. 예를 들어 무언가를 표현하려면 데이터 구조를 정의합니다. 프로세스도 예외는 아닙니다. 따라서 프로세스의 본질은 일련의 데이터를 저장하는 데이터 구조입니다. 운영체제는 모든 프로세스를 배열이나 연결리스트 형태로 관리합니다. 프로세스는 두 가지로 나누어진다고 할 수 있습니다.
1 시스템이 초기화될 때 첫 번째 프로세스,
2 첫 번째 프로세스를 제외한 나머지 프로세스는 fork 또는 fork+execute 시스템 호출로 생성됩니다.
먼저 프로세스 구조에 어떤 정보가 포함되어 있는지 살펴보겠습니다.

평균? 더 많은 맥락을 제공해 주세요.

위는 프로세스를 나타내는 구조의 주요 정보입니다. 그런 다음 구조는 프로세스를 나타냅니다. 우리는 포크가 상위 프로세스를 모듈로 사용하고 상위 프로세스의 구조를 복사한 다음 특정 필드를 수정한다는 것을 알고 있습니다. 새로운 과정이 됩니다. 실행이 호출되면 복사된 구조의 필드(예: 페이지 테이블, 코드 세그먼트 및 데이터 세그먼트)가 추가로 수정됩니다. 그리고 해당 데이터를 하드 디스크에서 메모리로 로드합니다. 그렇다면 첫 번째 프로세스는 어떻게 생성됩니까? 프로세스는 단지 구조이기 때문에 미리 구조를 정의하면 포크하지 않고도 프로세스를 생성할 수 있습니다.


2 프로세스 실행

시스템이 프로세스를 생성할 때 cs:ip 레지스터의 값을 설정합니다. 포크인 경우 ip는 포크 기능 이후의 문의 IP 주소입니다. 실행되면 컴파일러에서 IP 주소를 지정합니다. 무슨 일이 있어도 프로세스가 실행되기 시작하면 CPU는 cs:ip를 구문 분석하고 실행 명령을 받습니다. 그렇다면 cs:ip는 어떻게 구문 분석됩니까?
프로세스가 실행되면 tss 선택기(GDT 인덱스)가 tss 레지스터에 로드되고, 이후 tss의 컨텍스트도 cr3, ldt 선택기 등 해당 레지스터에 로드됩니다. tss 정보의 ldt 인덱스에 따라 먼저 GDT에서 프로세스 ldt 구조 데이터의 첫 번째 주소를 찾은 다음 코드 세그먼트와 같은 현재 세그먼트의 속성에 따라 cs에서 선택기를 얻습니다. ldt 테이블의 프로세스 선형 공간의 첫 번째 주소, 길이 제한, 권한 및 기타 정보. 선형 주소의 첫 번째 주소와 IP의 오프셋을 사용하여 선형 주소를 얻은 다음 페이지 디렉토리와 페이지 테이블을 통해 물리적 주소를 얻습니다. 물리 주소가 할당되지 않은 경우 페이지 폴트 예외 및 기타 처리가 수행됩니다. 수행됩니다.

3 프로세스 정지 및 깨우기

프로세스 정지, 차단 및 다중 프로세스. 우리는 일반적으로 이러한 개념을 자주 듣습니다. 이제 이러한 개념이 어떻게 구현되는지 살펴보겠습니다. 프로세스 일시 중단 또는 차단에는 두 가지 유형이 있습니다.
1 활성 정지. 수면 중에 프로세스가 간헐적으로 중단되도록 하세요. 수면의 원리는 이전에 분석한 바 있으므로 다시 분석하지는 않겠습니다. 일반적인 원칙

  • 은 타이머를 설정하고 만료 후 프로세스를 깨우는 것입니다.

  • 프로세스를 정지 상태로 수정하고 wake-up을 기다립니다.

2 패시브 정지.
수동적 일시 중단에는 다양한 시나리오가 있습니다. 주로 프로세스가 리소스에 적용되지만 리소스가 조건을 충족하지 않으면 운영 체제에 의해 프로세스가 일시 중단되는 경우입니다. 예를 들어 파이프를 읽을 때입니다. 파이프에서 읽을 데이터가 없으면 프로세스가 일시 중지됩니다. 파이프의 대기 큐에 삽입합니다.

평균? 더 많은 맥락을 제공해 주세요.

파이프에 콘텐츠가 기록되면 프로세스가 활성화됩니다. 프로세스는 일시 중단(신호로 깨울 수 있는 유형과 신호로 깨울 수 없는 유형의 두 가지 유형으로 구분)되고 깨우기 구현이 수행됩니다.


<code>// 当前进程挂载到睡眠队列p中,p指向队列头指针的地址<br>void sleep_on(struct task_struct **p)<br>{<br>    struct task_struct *tmp;<br><br>    if (!p)<br>        return;<br>    if (current == &(init_task.task))<br>        panic("task[0] trying to sleep");<br>    /*<br>        *p为第一个睡眠节点的地址,即tmp指向第一个睡眠节点<br>        头指针指向当前进程,这个版本的实现没有采用真正链表的形式,<br>        他通过每个进程在栈中的临时变量形成一个链表,每个睡眠的进程,<br>        在栈里有一个变量指向后面一个睡眠节点,然后把链表的头指针指向当前进程,<br>        然后切换到其他进程执行,当被wake_up唤醒的时候,wake_up会唤醒链表的第一个<br>        睡眠节点,因为第一个节点里保存了后面一个节点的地址,所以他唤醒后面一个节点,<br>        后面一个节点以此类推,从而把整个链表的节点唤醒,这里的实现类似nginx的filter,<br>        即每个模块保存后面一个节点的地址,然后把全局指针指向自己。<br>    */<br>    tmp = *p;<br>    *p = current;<br>    // 不可中断睡眠只能通过wake_up唤醒,即使有信号也无法唤醒<br>    current->state = TASK_UNINTERRUPTIBLE;<br>    // 进程调度<br>    schedule();<br>    // 唤醒后面一个节点<br>    if (tmp)<br>        tmp->state=0;<br>}<br><br>// 唤醒队列中的第一个节点,并清空链表,因为第一个节点会向后唤醒其他节点<br>void wake_up(struct task_struct **p)<br>{<br>    if (p && *p) {<br>        (**p).state=0;<br>        *p=NULL;<br>    }<br>}</code>

우리는 프로세스의 구현이 우리가 일반적으로 코드를 작성하는 방법, 즉 데이터 구조를 정의한 다음 데이터 구조를 작동시키는 알고리즘을 구현하는 것과 유사하다는 것을 발견했습니다. 물론, 여기에는 기본 하드웨어가 포함되기 때문에 운영 체제의 구현은 우리 코드보다 훨씬 더 복잡합니다.

위 내용은 평균? 더 많은 맥락을 제공해 주세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제