스레드 대 (포크) 프로세스


9

Linux 응용 프로그램은 일반적으로 exec (execve () 사용)를 사용하지만 Java 응용 프로그램 및 특정 Apache MPM은 스레딩을 사용합니다. 분기하는 경우 fork + exec를 사용하여 프로세스를 생성하면 스레딩의 상위 버전은 무엇입니까? JVM 또는 Worker MPM은 어떻게 스레드를 생성합니까?


2
Stackoverflow를 확인하십시오. 이것의 일부를 설명하는 몇 가지 Q & A가 있습니다.
Henk Langeveld

답변:


13

스레드와 프로세스의 기본 개념은 거의 같습니다. 실행 경로를 분기합니다. 그렇지 않으면 스레드와 프로세스가 메모리와 다릅니다. 즉, 프로세스는 VM 공간이 다르지만 스레드는 분할 전에 존재하는 모든 것을 공유합니다.

clone () 호출 (man 2 clone)을 사용하여 스레딩 및 포크 작업의 기초

fork (2)와 달리 clone ()을 사용하면 하위 프로세스가 실행 컨텍스트의 일부를 메모리 공간, 파일 디스크립터 테이블 및 신호 핸들러 테이블과 같은 호출 프로세스와 공유 할 수 있습니다. (이 매뉴얼 페이지에서 "호출 프로세스"는 일반적으로 "부모 프로세스"에 해당합니다. 그러나 아래의 CLONE_PARENT에 대한 설명을 참조하십시오.)

clone ()의 주된 용도는 공유 메모리 공간에서 동시에 실행되는 프로그램에서 스레드, 즉 여러 제어 스레드를 구현하는 것입니다.

차이점은 clone ()에 전달 된 플래그에서 비롯됩니다. 매뉴얼 페이지에서 볼 수 있듯이 포크와 스레딩은 clone ()에 대한 미리 정의 된 매개 변수 집합입니다. 그러나 사용자 정의 작업을 수행 할 수도 있습니다.


1
음? 뭐? 프로세스를위한 별도의 메모리 공간은 큰 문제이므로 주제에 관한 모든 책을 다시 읽으십시오. 또한 커널이 충돌하는 코드를 잡아내는 데 도움이되는 반면, 커널은 개별 스레드가 haywire / trespasses로가는 프로세스를 간단히 종료시킵니다.
0xC0000022L

3
@ 0xC0000022L 당신의 주장은 대답처럼 모순되지 않습니다.
Ruslan

1
@Ruslan : 나는달라고 간청한다 : "[...] 아이디어는 거의 같다"? 스레드의 기본 개념은 실제로 동시성이지만 프로세스의 경우 완전히 다른 이야기입니다.
0xC0000022L

4
@ 0xC0000022L V13의 대답에서 중요한 부분을 놓쳤다. "실행 경로를 분기"-스레드와 프로세스의 차이점이 아니라 스레드 생성 방법에 대한 질문입니다.
Izkata

@ 이즈 카타 : 전혀. 나는 이것이 올바른 주장이 아니라고 생각합니다.
0xC0000022L

8

대부분의 비 유닉스 멀티 프로세싱 운영 체제 (OS)는 "spawn ()"호출 또는 이와 유사한 것을 사용하여 새로운 OS 프로세스 또는 제어 흐름을 생성합니다. Spawn ()은 많은 옵션과 많은 오버 헤드를 가진 매우 복잡한 호출 인 경향이 있습니다. 유닉스의 혁신 중 하나는 fork () 프로세스를 생성하는 오버 헤드가 훨씬 적은 방법을 제공하는 것이 었습니다. 유닉스는 exec ()를 사용하여 spawn ()의 나머지 절반 전에 임의의 양의 처리를 허용함으로써 spawn ()에 필요한 많은 옵션을 처리했습니다.

유닉스 및 이의 변형이 점점 더 많이 사용됨에 따라, 낮은 오버 헤드 프로세스 생성이 유용한 것으로 밝혀졌다. 실제로 사람들은 프로세스를 만드는 데 드는 오버 헤드를 낮추기 위해 너무 많이 사용되었으므로 "스레드"라는 아이디어가 탄생했습니다. 원래 스레드는 시작 프로세스에 의해 완전히 처리되었습니다 (그리고 JVM과 같은 프로그램은 "그린 스레드"로이를 수행 할 수 있습니다). 그러나 다중 스레드 스케줄링 처리는 까다 롭고 자주 잘못 수행되었습니다. 따라서 OS가 스케줄링을 처리하는 스레드를 수행하는 더 쉽고 중간적인 방법이 있지만 스레드간에 주소 공간을 공유함으로써 일부 오버 헤드가 절약됩니다.

귀하의 질문은 모두 "스레드"인 여러 가지 관련 개념이 있기 때문에 대답하기가 어렵습니다. 상세하게는 어떤 것을 참조하고 있는지를 설명하기 위해 형용사가 필요합니다. 반면에 차이점을 이해하면 원하는 특정 답변으로 이어질 수 있습니다. 자세한 내용은 "경량 프로세스", "사용자 스레드"및 "rfork ()"와 같은 항목을 찾아보십시오.


1
"멀티 스레드 스케줄링 처리는 까다 롭고 자주 잘못 수행되었습니다"인용이 필요했습니다. 사용자 공간 스레드를 구현하는 것은 문제가되지 않습니다. 사용자 공간 스레드의 문제점은 스레드가 차단 시스템 호출을 수행 하면 모든 스레드가 차단 된다는 것 입니다. 이를 피할 수있는 유일한 방법은 시스템 레벨 스레드를 사용하는 것입니다.
Bakuriu

1
흥미롭게도, 윈도우는 유닉스의 혁신을 포함하지 않았다 : 그것은 가지고 CreateProcess()있지만, 아무 유사한 fork().
Ruslan

2
@Bakuriu-다중 처리 스케줄러 구축, 공정성 유지, 기아 방지, 우선 순위 처리 등 많은 기사를 찾아보십시오. 사용자 공간 스레드를 구현하는 것은 문제가 아닙니다. 사소한 예제를 예약하는 것은 어렵습니다.
mpez0

@Ruslan : Windows에서 포크 할 수 있으며 Win32 API의 일부가 아닙니다. Nebbett의 "Windows NT / 2000 Native API"를 읽으십시오. 그는 흉내 낸 구현이있다 fork().
0xC0000022L

3

쓰레드와 포킹은 실제로 유닉스 / 리눅스 시스템에 존재하고 C / C ++에서 사용될 수있는 두 가지 다른 개념입니다.

fork ()의 ​​개념은 (매우 기본적으로) 부모 프로세스와 동일한 실행 코드를 가지며 포크 라인에서 실행을 시작하는 별도의 프로세스를 만드는 것입니다. exec 함수와 함께 포크를 사용하는 목적은 exec 함수가 종료 될 때 호출 한 프로세스를 닫는 것입니다. 따라서 일반적으로 각 프로세스의 PID (자식은 항상 0 임)를 가져 와서 자식이 exec 함수 실행을 마칠 때까지 부모를 기다리십시오.

스레드는 병렬 처리에 사용됩니다 (부모는 보통 포크 프로그램에서 자식을 기다립니다). C / C ++의 pthread (Google 검색 수행)와 같은 스레드는 기본 프로세스와 병렬로 실행되며 전역 변수 및 전역 함수를 원래 프로그램과 공유 할 수 있습니다. Java 스레드는 비슷하게 작동하므로 포크 프로세스보다 스레드와 더 유사하게 작동한다고 생각합니다.

기본적으로 포크와 스레딩에는 차이가 있습니다. 그들은 분명히 다른 일을합니다 (비슷한 것처럼 보이지만). 이러한 개념은 이해하기 어려울 수 있지만, 개념을 이해하려는 정직한 욕구가 있다면 광범위한 연구를 통해 학습 할 수 있습니다.

편집 # 1

포크와 스레드를 호출하고 사용하는 방법에 대한 다음 예를 참조하십시오. exec 함수의 동작과 메인 프로그램에 미치는 영향에 유의하십시오.

http://www.jdembrun.com:4352/computerScience/forkVSthread.zip


2
병렬 처리에도 포크 (exec가 있거나없는)를 사용할 수 있습니다. "exec 함수가 종료 될 때 호출 한 프로세스를 닫습니다."라는 말의 의미가 확실하지 않습니다. exec는 프로세스가 끝나면 실행이 완료된 상태입니다. 또한 pthreadAPI를하지 스레드 구현입니다.
Mat

포크로 OS 교사를 인용하고 있습니다. 그가 우리에게 말한 것에 따르면, 그렇습니다. 포크는 병렬로 실행될 수 있지만 exec 함수를 사용하면 마지막 것입니다. pthread는 예제로 사용되었습니다.
jaredad7

Exec은 분기 프로세스의 마지막 명령이 아니라 호출자의 코드에서 마지막 호출입니다. 분기 된 프로세스는 실행 된 코드를 계속 실행합니다.
Mat

귀하의 의견은 이러한 것들을 테스트하라는 메시지를 표시했습니다. 포크와 스레드에서 사용될 때 exec 함수의 동작과 프로그램에 미치는 영향을 보여주는 일부 C ++ 프로그램을 작성했습니다. 위의 편집 내용을 참조하십시오.
jaredad7

나는 대부분의 사람들이 그것을 다운로드 귀찮게하지 않을까 걱정이다. 또한 예제는 주소 공간을 공유하거나 관련이없는 모델 간의 흥미로운 차이점을 보여주지 않습니다 .
Mat

1

JVM과 Apache MPM은 모두 원시 스레드를 위해 커널을 사용합니다. 즉, OS를 사용하여 예약합니다. 물론 둘 다 물건을 추적하기 위해 자체 API가 필요합니다.

Stackoverflow는 이미 이것을 다루는 몇 가지 질문이 있습니다.

  1. JVM 기본 스레드 . 자세한 내용은 이 답변 을 확인하십시오 .

  2. Apache에는 두 가지 유형의 MPM이 있습니다 : Prefork, 스레드 당 하나의 프로세스, 여러 스레드를 처리하는 Worker : Apache MPMs . 에 대한 참조를 확인하십시오codebucket


1

분기하는 경우 fork + exec를 사용하여 프로세스를 생성하면 스레딩의 상위 버전은 무엇입니까? JVM 또는 Worker MPM은 어떻게 스레드를 생성합니까?

그것은 플랫폼에 따라 다르지만 리눅스에서는 다른 많은 POSIX 호환 시스템 이 사용자 랜드 스레딩 API 인 pthreads 의 로컬 구현을 사용한다고 가정 합니다. 예 :

#include <pthread.h>

pthread_t tid;
pthread_create(&tid, NULL, somefunc, NULL);

somefunc첫 번째 실행 지점으로 새 스레드 호출 을 시작합니다 .

그들은 같은 글로벌 공유 점에서 포크 구별 - 당신은 또한 스레드를 만들 수 있습니다 대신 (그러나 각각 독립적으로 실행 주 스레드의 중복 사본을 얻는, 부모 프로세스의 메모리 공간을 스택 자신의 메모리) - clone()pthreads를 기반으로 하는 시스템 호출이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.