2010-04-29 7 views
7

스왑 파티션이없는 임베디드 플랫폼에서 주 프로세스가 사용 가능한 실제 메모리의 대부분을 차지하는 응용 프로그램이 있습니다. 문제는 응용 프로그램에서 외부 셸 스크립트를 시작하려고하지만 fork()를 사용하면 자식 프로세스 (궁극적으로 훨씬 작은 것으로 execl 될)를 만들기 전에 원래 프로세스의 2 배에 해당하는 충분한 메모리가 있어야합니다. .많은 메모리를 사용하는 프로세스에서 메모리가 부족한 fork()를 사용하지 않고 어떻게 쉘을 생성 할 수 있습니까?

그래서 fork()의 ​​메모리 오버 헤드없이 C 프로그램에서 쉘 스크립트를 호출 할 수있는 방법이 있습니까?

필자는 쉘을 생성하는 보조 프로세스가 작거나 파일을 터치하여 신호를 보내는 "감시자"스크립트를 사용하는 등의 해결 방법을 고려해 왔지만 훨씬 간단한 것이 더 있습니다.

+0

참조 그렉 Hewgill의 답변을.이것은 플랫폼에 다소 의존합니다. 사용중인 플랫폼 (예 : MMU가 있습니까?)에 대해 자세히 설명해 주실 수 있습니까? – ConcernedOfTunbridgeWells

+0

어제 * 질문에 속지 않습니다. ?? http://stackoverflow.com/questions/2731531/faster-forking-of-large-processes-on-linux –

+0

예, 아니요, @Pavel,이 하나는 Linux에만 국한되지 않으며 추가 정보가 있습니다. 실행중인 항목 - 쉘 스크립트. 다른 질문자는 스레드를 사용하기 위해 응용 프로그램을 다시 작성할 수있는 옵션을 가지고있을 수도 있습니다 (exec'ed 프로그램이 bash/ksh/other-shell이 ​​아닌 자신의 제어하에 실행 가능할 경우).이 경우에는 그렇지 않을 수도 있습니다. – paxdiablo

답변

8

일부 UNIX 구현에서는 vfork (단일 UNIX 사양의 일부)을 제공하며 이는 모든 항목을 부모와 공유한다는 점을 제외하고 정확히 fork과 같습니다. vfork

, 당신은 아이에서 할 수있는 일의 매우 제한된 수의 다른 프로세스 주소 공간을 덮어 exec를 호출하기 전에이있다 - 그것은 fork/exec를 들어, vfork가 만들어진 것을 기본적으로 fork의 최소 복사 버전입니다 순서.

+0

고마워요.이게 내가 필요한 것입니다. – kdt

6

시스템에 MMU가있는 경우 일반적으로 fork()이 호출 될 때 실제로 더 많은 메모리를 할당하지 않는 copy-on-write를 사용하여 fork()이 구현됩니다. 추가 메모리는 부모 프로세스와 공유되는 페이지에 을 쓰는 경우에만 할당됩니다. exec() 그러면 해당 페이지가 삭제됩니다.

MMU가 없다는 것을 알고 있다면 실제로 fork()이 실제 사본을 사용하여 구현됩니다. 또 다른 접근법은 파이프를 사용하여 통신하는 서브 쉘을 생성하는 도우미 프로세스를 갖는 것입니다.

+0

스왑 파티션이없는 일반적인 리눅스 2.6 시스템에서 이것을 테스트했습니다. 부모 프로세스가 약 300 megs 일 때 fork()를 사용하기 위해 top에 의해보고 된 것과 같이 적어도 200 MB의 여유 메모리가 필요하다는 것을 알았습니다. 더 작 으면 오류를 반환합니다. 나는 COW가 일어난다 고 생각한다. 리눅스가 스왑 파티션을 가지고있어 쓰기만 할 때까지 페이지를 복사 할 필요는 없다고 믿을 수 있다고 생각하면된다. – kdt

+3

나는 오버 커밋 설정 방법에 달려 있다고 생각합니다. Linux는 여전히 COW이지만 사용 가능한 VM에 대한 페이지 수를 계산합니다. 결과가 가상 메모리를 초과하면 (페이지가 수정되어 복사해야하는 경우) 실패합니다. 스왑을 사용하면 커널이 사용 가능한 VM을 더 크게 고려할 수 있습니다. – MarkR

-1

이 경우에는 신중한 움직임이 쉘 스크립트 (가능한 경우)를 C로 이식하고 프로세스 내에서 실행하는 것처럼 들립니다. 그래서 당신은 전혀 포크 할 필요가 없습니다.

다시; 나는 실제로 당신이 무엇을하려고하는지 모른다. do.

-3

프로세스를 포어 팅하여 셸을 생성하는 대신 프로세스 내에서 (포 그라운드에서) 셸을 실행 한 다음 셸 내에서 포크하십시오./스크립트/bgtask의 존재와

system("/bin/ash /scripts/bgtask"); 

:

/bin/ash /scripts/propertask & 

당신은 쉘에서 사용하는 전용 메모리를 두 배로이 방법이 아닌 메인 프로그램으로. 주 프로그램은 두 개의 셸을 생성하는 동안 바쁘게됩니다. 원본은 bgtask를 시작하고 배경 복제본은 시작된 다음 첫 번째 셸에서 할당 한 메모리는 다시 자유입니다.

+1

시스템이 fork/exec/wait로 구현되어있어 해결하고자하는 문제와 동일한 문제가 발생할 수 있습니다. – paxdiablo

+0

paxdiablo가 정확합니다. system()은 fork()를 내부적으로 사용합니다. 맨 페이지 이벤트는 "... 예를 들어 fork()가 실패했습니다 ...": http://linux.die.net/man/3/system – kdt

관련 문제