Linux 프로세스 잠자기 및 깨우기: 시스템을 더욱 에너지 절약적이고 효율적으로 만듭니다.
Linux 시스템은 다중 작업의 동시 실행을 지원하는 운영 체제로, 동시에 여러 프로세스를 실행할 수 있어 시스템 활용도와 효율성이 향상됩니다. 그러나 모든 프로세스가 항상 프로세서 리소스를 점유할 필요는 없습니다. 일부 프로세스는 특정 조건에서 일시적으로 프로세서를 포기하고 절전 상태로 들어가서 조건이 충족될 때까지 기다린 다음 깨어나 실행을 계속할 수 있습니다. 이것의 장점은 프로세서 리소스를 절약하고 실행해야 하는 다른 프로세스에 더 많은 기회를 제공할 수 있으며 시스템의 전력 소비와 발열을 줄이고 시스템의 안정성과 수명을 향상시킬 수 있다는 것입니다. 이 기사에서는 프로세스의 절전 이유, 절전 유형, 절전 기능, 깨우기 기능 및 깨우기 메커니즘을 포함하여 Linux 시스템 프로세스의 절전 및 깨우기 방법을 소개합니다.
물론 프로세스는 CPU 제어를 적극적으로 해제할 수도 있습니다. Schedule() 함수는 다른 프로세스가 CPU를 점유하도록 예약하기 위해 프로세스에서 적극적으로 호출할 수 있는 예약 함수입니다. CPU를 적극적으로 포기한 프로세스가 CPU를 점유하도록 다시 예약되면 마지막으로 실행을 중지한 위치에서 실행이 시작됩니다. 즉, Schedule()을 호출하는 다음 코드 줄부터 실행이 시작됩니다.
때때로 프로세스는 장치 초기화, I/O 작업 완료 또는 타이머 만료와 같은 특정 이벤트가 발생할 때까지 기다려야 합니다. 이 경우 프로세스는 실행 큐에서 제거되고 대기 큐에 추가되어야 합니다. 이때 프로세스는 슬립 상태에 진입합니다.

Linux의 프로세스 절전 상태 분류
하나는 중단 가능한 절전 상태이고 상태 플래그는 TASK_INTERRUPTIBLE
입니다.
다른 하나는 중단할 수 없는 절전 상태이며 상태 플래그는 TASK_UNINTERRUPTIBLE입니다. 인터럽트 가능한 절전 상태의 프로세스는 특정 조건이 충족될 때까지 절전 모드로 유지됩니다. 예를 들어 하드웨어 인터럽트 발생, 프로세스가 기다리고 있는 시스템 리소스 해제, 신호 전달 등이 프로세스를 깨우는 조건이 될 수 있습니다. 무정전 슬립 상태는 인터럽트 가능 슬립 상태와 유사하지만 한 가지 예외가 있다. 즉, 이 슬립 상태에 신호를 전달하는 프로세스는 상태를 변경할 수 없다. 즉, 깨우라는 신호에 응답하지 않는다는 것이다. 중단 불가능한 절전 상태는 일반적으로 덜 사용되지만 일부 특정 상황에서는 여전히 매우 유용합니다. 예를 들어 프로세스는 특정 이벤트가 발생할 때까지 기다려야 하며 중단될 수 없습니다.
최신 Linux 운영 체제에서는 일반적으로 프로세스가 Schedule()을 호출하여 절전 상태로 전환됩니다.
실행 중인 프로세스를 절전 모드로 전환하는 방법을 보여줍니다.
으아악
프로세스 구조. set_current_state()는 프로세스 상태를 실행 상태 TASK_RUNNING에서 절전 상태로 변경합니다
TASK_INTERRUPTIBLE. TASK_RUNNING 상태의 프로세스에 의해 스케줄()이 예약된 경우, 스케줄()은 CPU를 점유하도록 다른 프로세스를 예약합니다. TASK_INTERRUPTIBLE 또는 TASK_UNINTERRUPTIBLE 상태의 프로세스에 의해 스케줄()이 예약된 경우 추가 단계가 있습니다. 실행 중: 현재 실행 중인 프로세스는 다른 프로세스가 예약되기 전에 실행 큐에서 제거됩니다. 이로 인해 실행 중인 프로세스가 더 이상 실행 큐에 없기 때문에 절전 모드로 전환됩니다.
방금 잠들었던 프로세스를 깨우기 위해 다음 함수를 사용할 수 있습니다.
wake_up_process(sleeping_task);
wake_up_process()를 호출한 후 잠자는 프로세스의 상태는 TASK_RUNNING으로 설정되고 스케줄러
실행 대기열에 추가됩니다. 물론 이 프로세스는 다음에 스케줄러가 예약한 경우에만 실행될 수 있습니다.
잘못된 깨우기
거의 모든 경우 특정 조건을 확인하고 조건이 충족되지 않으면 프로세스가 절전 모드로 전환됩니다. 하지만 가끔
그러나 판단 조건이 참이면 프로세스는 계속 Sleep 상태가 됩니다. 이것이 바로 Invalid Wake-up 문제입니다. 운영 체제에서 여러 프로세스가 공유 데이터에 대해 일부 처리를 시도하고 최종 결과가 프로세스가 실행되는 순서에 따라 달라지는 경우 이는 운영 체제의 일반적인 문제입니다. up 그것은 바로 경쟁적 상황 때문이다.
두 개의 프로세스 A와 B가 있다고 가정해 보겠습니다. 프로세스 A는 연결된 목록이 비어 있지 않은지 확인해야 합니다.
테이블의 데이터는 일부 작업을 진행 중이며 프로세스 B도 연결 목록에 노드를 추가하고 있습니다. 연결리스트가 비어 있으면 연산할 데이터가 없기 때문에 프로세스 A는 휴면상태가 되고, 프로세스 B가 연결리스트에 노드를 추가하면 프로세스 A를 깨웁니다. 코드는 다음과 같습니다.
프로세스:
으아악
B 과정:
100 spin_lock(&list_lock); 101 list_add_tail(&list_head, new_node); 102 spin_unlock(&list_lock); 103 wake_up_process(processa_task);
这里会出现一个问题,假如当A进程执行到第3行后第4行前的时候,B进程被另外一个处理器调度
投 入运行。在这个时间片内,B进程执行完了它所有的指令,因此它试图唤醒A进程,而此时的A进程还没有进入睡眠,所以唤醒操作无效。在这之后,A 进程继续执行,它会错误地认为这个时候链表仍然是空的,于是将自己的状态设置为TASK_INTERRUPTIBLE然后调用schedule()进入睡 眠。由于错过了B进程唤醒,它将会无限期的睡眠下去,这就是无效唤醒问题,因为即使链表中有数据需要处理,A 进程也还是睡眠了。
避免无效唤醒
如何避免无效唤醒问题呢?我们发现无效唤醒主要发生在检查条件之后和进程状态被设置为睡眠状
态之前, 本来B进程的wake_up_process()提供了一次将A进程状态置为TASK_RUNNING 的机会,可惜这个时候A进程的状态仍然是TASK_RUNNING,所以wake_up_process()将A进程状态从睡眠状态转变为运行状态的努力 没有起到预期的作用。要解决这个问题,必须使用一种保障机制使得判断链表为空和设置进程状态为睡眠状态成为一个不可分割的步骤才行,也就是必须消除竞争条 件产生的根源,这样在这之后出现的wake_up_process ()就可以起到唤醒状态是睡眠状态的进程的作用了。
找到了原因后,重新设计一下A进程的代码结构,就可以避免上面例子中的无效唤醒问题了。
A进程:
1 set_current_state(TASK_INTERRUPTIBLE); 2 spin_lock(&list_lock); 3 if(list_empty(&list_head)) { 4 spin_unlock(&list_lock); 5 schedule(); 6 spin_lock(&list_lock); 7 } 8 set_current_state(TASK_RUNNING); 9 10 /* Rest of the code ... */ 11 spin_unlock(&list_lock);
可以看到,这段代码在测试条件之前就将当前执行进程状态转设置成TASK_INTERRUPTIBLE了,并且在链表不为空的情况下又将自己置为TASK_RUNNING状态。这样一来如果B进程在A进程进程检查
了链表为空以后调用wake_up_process(),那么A进程的状态就会自动由原来TASK_INTERRUPTIBLE
变成TASK_RUNNING,此后即使进程又调用了schedule(),由于它现在的状态是TASK_RUNNING,所以仍然不会被从运行队列中移出,因而不会错误的进入睡眠,当然也就避免了无效唤醒问题。
Linux内核的例子
在Linux操作系统中,内核的稳定性至关重要,为了避免在Linux操作系统内核中出现无效唤醒问题,
Linux内核在需要进程睡眠的时候应该使用类似如下的操作:
/* ‘q’是我们希望睡眠的等待队列 /
DECLARE_WAITQUEUE(wait,current);
add_wait_queue(q, &wait);
set_current_state(TASK_INTERRUPTIBLE);
/ 或TASK_INTERRUPTIBLE /
while(!condition) / ‘condition’ 是等待的条件*/
schedule();
set_current_state(TASK_RUNNING);
remove_wait_queue(q, &wait);
上面的操作,使得进程通过下面的一系列步骤安全地将自己加入到一个等待队列中进行睡眠:首先调
用DECLARE_WAITQUEUE ()创建一个等待队列的项,然后调用add_wait_queue()把自己加入到等待队列中,并且将进程的状态设置为 TASK_INTERRUPTIBLE 或者TASK_INTERRUPTIBLE。然后循环检查条件是否为真:如果是的话就没有必要睡眠,如果条件不为真,就调用schedule()。当进程 检查的条件满足后,进程又将自己设置为TASK_RUNNING 并调用remove_wait_queue()将自己移出等待队列。
从上面可以看到,Linux的内核代码维护者也是在进程检查条件之前就设置进程的状态为睡眠状态,
然后才循环检查条件。如果在进程开始睡眠之前条件就已经达成了,那么循环会退出并用set_current_state()将自己的状态设置为就绪,这样同样保证了进程不会存在错误的进入睡眠的倾向,当然也就不会导致出现无效唤醒问题。
下面让我们用linux 内核中的实例来看看Linux 内核是如何避免无效睡眠的,这段代码出自Linux2.6的内核(linux-2.6.11/kernel/sched.c: 4254):
4253 /* Wait for kthread_stop */
4254 set_current_state(TASK_INTERRUPTIBLE);
4255 while (!kthread_should_stop()) {
4256 schedule();
4257 set_current_state(TASK_INTERRUPTIBLE);
4258 }
4259 __set_current_state(TASK_RUNNING);
4260 return 0;
上面的这些代码属于迁移服务线程migration_thread,这个线程不断地检查kthread_should_stop(),
直 到kthread_should_stop()返回1它才可以退出循环,也就是说只要kthread_should_stop()返回0该进程就会一直睡 眠。从代码中我们可以看出,检查kthread_should_stop()确实是在进程的状态被置为TASK_INTERRUPTIBLE后才开始执行 的。因此,如果在条件检查之后但是在schedule()之前有其他进程试图唤醒它,那么该进程的唤醒操作不会失效。
이 글에서는 슬립 이유, 슬립 유형, 슬립 기능, 웨이크업 기능 및 프로세스의 웨이크업 메커니즘을 포함하여 Linux 시스템 프로세스의 슬립 및 웨이크업 방법을 소개합니다. 이 지식을 이해하고 숙달함으로써 Linux 시스템의 프로세스를 더 잘 관리하고 제어할 수 있어 시스템을 더욱 에너지 절약적이고 효율적으로 실행할 수 있습니다. 물론 Linux 시스템에는 잠자기 및 깨우기 프로세스에 대한 세부 정보와 기술이 많이 있으므로 계속해서 배우고 연습해야 합니다
위 내용은 Linux 프로세스 잠자기 및 깨우기: 시스템을 더욱 에너지 절약적이고 효율적으로 만듭니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

Linux 시스템의 5 가지 기본 구성 요소는 다음과 같습니다. 1. Kernel, 2. System Library, 3. System Utilities, 4. 그래픽 사용자 인터페이스, 5. 응용 프로그램. 커널은 하드웨어 리소스를 관리하고 시스템 라이브러리는 사전 컴파일 된 기능을 제공하며 시스템 유틸리티는 시스템 관리에 사용되며 GUI는 시각적 상호 작용을 제공하며 응용 프로그램은 이러한 구성 요소를 사용하여 기능을 구현합니다.

git 저장소 주소를 보려면 다음 단계를 수행하십시오. 1. 명령 줄을 열고 리포지토리 디렉토리로 이동하십시오. 2. "git remote -v"명령을 실행하십시오. 3. 출력 및 해당 주소에서 저장소 이름을 봅니다.

메모장은 Java 코드를 직접 실행할 수는 없지만 다른 도구를 사용하여 명령 줄 컴파일러 (Javac)를 사용하여 Bytecode 파일 (filename.class)을 생성하면 달성 할 수 있습니다. Java Interpreter (Java)를 사용하여 바이트 코드를 해석하고 코드를 실행하고 결과를 출력하십시오.

Sublime에서 코드를 실행하는 6 가지 방법이 있습니다. 핫키, 메뉴, 빌드 시스템, 명령 줄, 기본 빌드 시스템 설정 및 사용자 정의 빌드 명령, 프로젝트/파일을 마우스 오른쪽 단추로 클릭하여 개별 파일/프로젝트를 실행합니다. 빌드 시스템 가용성은 숭고한 텍스트 설치에 따라 다릅니다.

Linux의 주요 용도에는 다음이 포함됩니다. 1. 서버 운영 체제, 2. 임베디드 시스템, 3. 데스크탑 운영 체제, 4. 개발 및 테스트 환경. Linux는이 분야에서 뛰어나 안정성, 보안 및 효율적인 개발 도구를 제공합니다.

GIT 소프트웨어 설치 단계는 다음 단계가 포함됩니다. 설치 패키지를 다운로드하고 설치 패키지를 실행하여 설치 구성 GIT 설치 GIT BASH (Windows 만)를 확인하십시오.

Laravel을 설치하려면 다음 단계를 순서대로 수행하십시오. Composer 설치 (MacOS/Linux 및 Windows) 설치 LARAVEL 설치 프로그램 새 프로젝트 시작 서비스 액세스 애플리케이션 (URL : http://127.0.1:8000) 데이터베이스 연결 (필요한 경우)을 설정하십시오.

개발 환경을 사용자 정의하는 방법에는 여러 가지가 있지만 글로벌 GIT 구성 파일은 사용자 이름, 이메일, 우선 텍스트 편집기 및 원격 분기와 같은 사용자 정의 설정에 가장 많이 사용되는 파일입니다. 글로벌 git 구성 파일에 대해 알아야 할 주요 사항은 다음과 같습니다.
