9.プロセス制御

30908 ワード

9.1作成プロセス


1.プロセスの作成

  • fork()システムコール
    -親プロセスを完全にコピーして、新しい子プロセス(自己コピー)
  • を作成します.
    ex) fork1.c
    #include <stdio.h>
    #include <unistd.h>
    /* 자식 프로세스를 생성한다. */
    int main()
    { 
    int pid;
    printf("[%d] 프로세스 시작 \n", getpid());
    pid = fork();
    printf("[%d] 프로세스 : 리턴값 %d\n", getpid(), pid);
    }
    
    [3156 3]プロセスの開始
    [31563]プロシージャ:戻り値31564
    [3156 4]プロシージャ:戻り値0

    2.親プロセスと子プロセスの区別

  • fork()を呼び出すと、戻り値が異なるため、この戻り値を使用して親プロセスと子プロセスを区別し、異なる操作を実行できます.
  • 
    pid = fork();
    if(pid==0)
    { 자식프로세스의 실행코드 }
    
    else
    { 부모프로세스의 실행코드 }
    ex) fork2.c
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    /* 부모 프로세스가 자식 프로세스를 생성하고 서로 다른 메시지를 프린트 */
    
    int main()
    {
    	int pid;
    	pid = fork();
    
    	if(pid==0)
    	{
    		printf("[CHILD] : HELLO~ pid = %d\n",getpid());
    	}
    	else
    	{
    		printf("[PARENT] : HELLO~ pid= %d\n",getpid());
    	}
    }
    
    
    ex) fork3.c
    #include <stdlib.h>
    #include <stdio.h>
    
    /* 부모 프로세스가 두 개의 자식 프로세스를 생성한다. */
    
    int main() 
    {
    int pid1, pid2;
    
    pid1 = fork();
      if (pid1 == 0) {
      printf("[Child 1] : Hello, world ! pid=%d\n", getpid());
      exit(0);
      }
    
    pid2 = fork();
      if (pid2 == 0) {
      printf("[Child 2] : Hello, world ! pid=%d\n", getpid());
      exit(0);
    
    }
    
    }

    3.プロセス待ち:wait()

  • サブプロセスのいずれかが終了するのを待つ.
    -サブプロセスを終了する終了コードはstatusに格納されます.
    は、
  • の終了サブプロセスの番号
  • を返します.
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    int main()
    {
    	int pid, child, status;
    	printf("[%d] 부모 프로세스 시작 \n", getpid());	
    
    	pid = fork();
    
    	if (pid == 0) {
    		printf("[%d] 자식 프로세스 시작 \n", getpid( ));
    		exit(1);
    	}
    
    	child = wait(&status); // 자식 프로세스가 끝나기를 기다린다.
    	printf("[%d] 자식 프로세스 %d 종료 \n", getpid(), child);
    	printf("\t종료 코드 %d\n", status>>8);
    
    }
    
    
    [23184]親プロセスの開始
    [2385]サブプロセスの開始
    サブプロセス23185の終了
    終了コード1

    4.fork()の後にファイルを共有する

  • 子親のfd表をコピーします.
    -親と子が同じファイルを共有するディスク・レバー
    共有
  • 等ファイルオフセット
  • 親子の輸出混在
  • 子供の性質を継承しない
    戻り値
  • fork()
  • フローID
  • ファイルロック
  • に設定された目覚まし時計と信号
  • 9.2プログラムの実行


    プログラムの実行


  • fork()以降のサブプロセスは親プロセスと同じコードを実行する

  • サブプロセスで3つの新しいプログラムを実行
    使用シヨウ:exec()システムコールexec()システムコール
    :プロセス内のプログラムを新しいプログラムに置き換える

  • 通常fork()の後にexec()を実行します.
  • 実行プログラム:exec()

  • プロセス呼び出しexec()
    :新しいプロセスのプログラムが新しいプログラムに置き換えられます(自己置換)
    :新しいプログラムのmain()から実行します.
  • exec()呼び出しが成功した場合、戻る場所はありません.
  • 成功したexec()呼び出しは、
  • を絶対に返さない.
  • は、通常、fork()の後にexec()を呼び出す.
    :新しい実行プログラムに関する情報をargumentsに渡します.
  • exec()呼び出しが成功した場合、
  • 子プロセスは新しいプログラムを実行し、親プロセスは次のコードを実行します.t
    
    if ((pid = fork()) == 0 ){
    exec( arguments );
    exit(1);
    }
    // 부모 계속 실행
    ex) execute1.c
    
    #include <stdio.h>
    /* 자식 프로세스를 생성하여 echo 명령어를 실행한다. */
    
    int main( ) 
    {
    
    printf("부모 프로세스 시작\n");
    
    // 자식프로세스 생성 
    if (fork( ) == 0) {
    execl("/bin/echo", "echo", "hello", NULL);
    fprintf(stderr,"첫 번째 실패"); 
    exit(1);
    }
    printf("부모 프로세스 끝\n");
    
    
    ex2) execute2.c
    #include <stdio.h>
    #include <stdlib.h>
    
    /* 자식프로세스를 생성하여 echo 명령어를 실행한다. */
    
    int main()
    {
    	printf("부모 프로세스 시작\n");
    	if(fork()==0)
    	{
    		execl("/bin/echo","echo","hello",NULL);
    		fprintf(stderr,"첫 번째 실패");
    		exit(1);
    	}
    	
    	if(fork()==0)
    	{
    		execl("/bin/date","date",NULL);
    		fprintf(stderr,"두 번째 실패");
    		exit(2);
    	}
    	
    	if (fork( ) == 0) 
    	{
    		execl("/bin/ls","ls", "-l", NULL);
    		fprintf(stderr,"세 번째 실패"); 
    		exit(3);
    	}
    	
    	printf("부모 프로세스 끝\n");
    	
    }
    ex) execute3.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <wait.h>
    
    /* 자식프로세스를 생성하여 echo 명령어를 실행한다. */
    
    int main(int argc, char* argv[])
    {
    	int child,pid,status;
    	
    	pid = fork();
    	
    	// 자식프로세스 
    	if(pid==0) 
    	{
    		execv(argv[1],&argv[1]);
    		fprintf(stderr,"%s:실행 불가\n",argv[1]);
    		
    	}
    	// 부모 프로세스 
    	else
    	{
    		child = wait(&status);
    		printf("[%d] 자식 프로세스 %d 종료\n",getpid(),pid);
    		printf("\t종료 코드 %d\n",status>>8);
    	}
    	
    }
    

    system()



  • サブプロセスを作成し、/bin/shで指定したコマンドを実行します.
    ex) system("date > file);

  • システム()関数実装
    使用シヨウ:fork()、exec()、waitpid()システムコール

  • 戻り値
    コマンドの終了コード:成功
    127:exec()失敗
    -1:その他のエラー

  • システム()実装
  • #include <sys/types.h> /* system.c */
    #include <sys/wait.h>
    #include <errno.h>
    #include <unistd.h>
    
    int system(const char *cmdstring) 
    {
    	pid_t pid; int status;
    	
    	if (cmdstring == NULL) /* 명령어가 NULL인 경우 */
    	return(1); 
    	
    	if ( (pid = fork()) < 0)
    	{
    		status = -1; /* /* 프로세스 생성 실패 */
    	} 
    	
    	else if (pid == 0) 
    	{ 	/* 자식 */
      		execl("/bin/sh", "sh", "-c", cmdstring, (char *) 0);
    		_exit(127); /* execl 실패 */
    	} 
    	
    	else 
    	{   /* 부모 */
    		while (waitpid(pid, &status, 0) < 0)
    			if (errno != EINTR) {
    			status = -1; /* waitpid()로부터 EINTR외의 오류 */
    			break;
    			}
    		
    	}
    	
    	return(status);
    	
    }