■Multiplexed I/O


1. 프로세스는 하나 이상의 file descriptor가 준비될 때 까지 Block에 들어감.

2. File descriptor 중 하나가 요청한 입출력 준비가 되면 시스템이 알려준다.

3. Block되어 있던 프로세스가 깨어난 후

4. 프로세스는 입출력 준비된 file descriptor들에 대해 처리한다.


//    select_test.c    //

#include <sys/time.h> 

#include <sys/types.h> 

#include <unistd.h> 

#include <fcntl.h> 

#include <stdlib.h> 

#include <string.h> 

#include <stdio.h> 


int main()

{

    int fd[2];

    int i;

    int n;

    int state;


    char buf[255];


    struct timeval tv;


    fd_set readfds, writefds;


    if ((fd[0] = open("testfile0", O_RDONLY)) == -1)

    {

        perror("file open error : ");

        exit(0);

    }

    if ((fd[1] = open("testfile1", O_RDONLY)) == -1)

    {

        perror("file open error : ");

        exit(0);

    }


    memset (buf, 0x00, 255);


    for(;;)

    {

        FD_ZERO(&readfds);

        FD_SET(fd[0], &readfds);

        FD_SET(fd[1], &readfds);


        state = select(fd[1]+1, &readfds, NULL, NULL, NULL);

        switch(state)

        {

            case -1:

                perror("select error : ");

                exit(0);

                break;


            default :

                for (i = 0; i < 2; i++)

                {

                    if (FD_ISSET(fd[i], &readfds))

                    {

                        while ((n = read(fd[i], buf, 255)) > 0)

                            printf("(%d) [%d] %s", state, i, buf);

                    }

                }

                memset (buf, 0x00, 255);

                break;

        }

        usleep(1000);

    }

}


# touch testfile0 testfile1
# cc seletc_test.c
# ./a.out &
[4] 11443
# echo hello >> testfile0
(2) [0] hello
echo word >> testfile1
(2) [1] word
echo good >> testfile0

# cat testfile0

hello

good

# cat testfile1

word



*입출력 리다이렉션
//    std.c    //

#include<unistd.h>
#include<sys/types.h>
#include<stdio.h>
#include<string.h>

#define STDIN 0
#define STDOUT 1
#define STDERR 2

#define ERRMSG "Devide Not Zero\n"

int main()
{
    int a;
    int b;
    char buf[80];

    read(STDIN, buf, 80);
    a = atoi(buf);

    read(STDIN, buf, 80);
    b = atoi(buf);
    if(b == 0)
    {
        write(STDERR, ERRMSG, strlen(ERRMSG));
        return 1;
    }

    sprintf(buf, "%d / %d = %d\n", a, b, (int)(a/b));

    write(STDOUT, buf, strlen(buf));
    return 0;
}

# cc std.c

# ./a.out


# ./a.out 

4

8

4 / 8 = 0


# ./a.out 

6

0

Devide Not Zero


# ./a.out 2>stderr.txt            -->2 : STDERR를 리다이렉션으로 stderr.txt에 저장
6
0
# cat stderr.txt 
Devide Not Zero

# ./a.out  1>stderr.txt
1
2
# cat stderr.txt 
1 / 2 = 0







■프로세스


//    fork.c    //
#include <stdio.h>
#include <stdlib.h> // for system()
#include <unistd.h> // for execl(), fork()
#include <wait.h>       // for wait()

int main(int argc, char *argv[])
{
    int pid;
    /* fork another process */
    pid = fork();
    if(pid < 0) {                       /* error occurred */
        fprintf(stderr,"Fork Failed");
        exit(-1);
    } else if (pid== 0) {       /* child process */
               // execl("/bin/ls", "ls", NULL);                ==>Child here! 없다
                //execl("/bin/ps", "ps", "aux", NULL);      ==>Child here! 없다
                //system("/bin/ps aux");                      ==>Child here! 없다있다
                printf("Child here!\n");
        //      for(;;) 
                sleep(1);
    } else {          /* parent process */
        wait(NULL);
        printf("Child Complete!\n");
        exit(0);
    }
}

# ./a.out 
Child here!
Child Complete!


 // execl("/bin/ls", "ls", NULL); 

# ./a.out 

a.out  execl.c fork.c orphan.c  prio.c  sched_param.c  wait.c  zombie.c

Child Complete!




*고아 프로세스 : 부모 프로세스가 먼저 종료된 경우 자동적으로 init의 상속이된다.


//    orphan.c    //

#include <sys/types.h>

#include <wait.h>

#include <stdio.h>


int main()

{

pid_t pid;

printf("I'm the original process : pid = %d, ppid = %d\n", 

getpid(), getppid());


pid =  fork();

if ( pid != 0 )  { /* parent process */

printf("I'm parent process : pid = %d, ppid = %d\n", 

getpid(), getppid());

printf("my child process : pid = %d\n", pid);

}

else { /* child process */

sleep(5);

printf("I'm child process : pid = %d, ppid = %d\n", 

getpid(), getppid());

}

/* parent & child  process */

printf("pid %d terminates.. \n", getpid());  

}



$ ./a.out 

I'm the original process : pid = 12382, ppid = 1623

I'm parent process : pid = 12382, ppid = 1623

my child process : pid = 12383

pid 12382 terminates.. 

$ ps -l

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD

0 S  1001  1623  1621  0  80   0 -  1518 wait   pts/0    00:00:00 bash

1 S  1001 12383     1  0  80   0 -   404 hrtime pts/0    00:00:00 a.out

0 R  1001 12386  1623  0  80   0 -   625 -      pts/0    00:00:00 ps







* 좀비 프로세스 : 실행이 종료되어 부모 프로세스가 반환 코드를 받을 때까지 프로세스 테이블 엔트리에 정보가 남아 있는 프로세스


//    Zombi.c    //

#include <sys/types.h>

#include <wait.h>

#include <stdlib.h>


int main()

{

   pid_t pid;

      

   pid = fork();


   if ( pid != 0 )  { /* parent process */

while(1) sleep(1000);

   }

   else { /* child  process */

exit(42);

   }


}



$ ./a.out &

[1] 12473

$ ps

  PID TTY          TIME CMD

 1623 pts/0    00:00:00 bash

12473 pts/0    00:00:00 a.out

12474 pts/0    00:00:00 a.out <defunct>

12475 pts/0    00:00:00 ps


$ kill 12473

$ ps

  PID TTY          TIME CMD

 1623 pts/0    00:00:00 bash

12478 pts/0    00:00:00 ps

[1]+  Terminated              ./a.out




*프로세스 상태 


//    prio.c    //


#include <stdio.h>

#include <sys/types.h>

#include <sys/resource.h>

#include <unistd.h>


int main(void)

{

//get process id of this process

pid_t current_pid = getpid();


//get priority   of this process

int priority = getpriority(PRIO_PROCESS, current_pid);        //nice값

printf("Process: %d, Priority: %d\n", current_pid, priority);

sleep(1);


/*

Try cases below... 


case 1: $ ./a.out &

$ ps -l

case 2: # ./a.out &

# ps -l

case 3: $ nice  -3 ./a.out &

$ ps -l

case 4: # nice --3 ./a.out &

# ps -l

/*결론 :  -3값은 sudo 권한만 가능 */

*/

/*  nice by +5 */

setpriority(PRIO_PROCESS, current_pid, 5);

priority = getpriority(PRIO_PROCESS, current_pid);

printf("Process: %d, Priority: %d\n", current_pid, priority);


system("ps -l");


sleep(1);


nice(-10); /* only superuser may lower priority */

priority = getpriority(PRIO_PROCESS, current_pid);

printf("Process: %d, Priority: %d\n", current_pid, priority);


system("ps -l");


return 0;

}



$ whoami

mds

$ cc prio.c 

$ ./a.out 


Process: 12723, Priority: 0

Process: 12723, Priority: 5

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD

0 S  1001  1623  1621  0  80   0 -  1519 wait   pts/0    00:00:00 bash

0 S  1001 12723  1623  0  85   5 -   404 wait   pts/0    00:00:00 a.out

0 S  1001 12724 12723  0  85   5 -   457 wait   pts/0    00:00:00 sh

0 R  1001 12725 12724  0  85   5 -   625 -      pts/0    00:00:00 ps

Process: 12723, Priority: 5

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD

0 S  1001  1623  1621  0  80   0 -  1519 wait   pts/0    00:00:00 bash

0 S  1001 12723  1623  0  85   5 -   404 wait   pts/0    00:00:00 a.out

0 S  1001 12726 12723  0  85   5 -   457 wait   pts/0    00:00:00 sh

0 R  1001 12727 12726  0  85   5 -   625 -      pts/0    00:00:00 ps


$ nice --3 ./a.out 
nice: cannot set niceness: Permission denied


# whoami

root

# cc prio.c 

# ./a.out 


Process: 12801, Priority: 0

Process: 12801, Priority: 5

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD

4 S     0 12769  1623  2  80   0 -  1533 wait   pts/0    00:00:00 bash

0 S     0 12801 12769  0  85   5 -   404 wait   pts/0    00:00:00 a.out

0 S     0 12802 12801  0  85   5 -   457 wait   pts/0    00:00:00 sh

4 R     0 12803 12802  0  85   5 -   625 -      pts/0    00:00:00 ps

Process: 12801, Priority: -5

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD

4 S     0 12769  1623  1  80   0 -  1533 wait   pts/0    00:00:00 bash

4 S     0 12801 12769  0  75  -5 -   404 wait   pts/0    00:00:00 a.out

0 S     0 12804 12801  0  75  -5 -   457 wait   pts/0    00:00:00 sh

4 R     0 12805 12804  0  75  -5 -   625 -      pts/0    00:00:00 ps







//    sched_param.c    //

#include <stdio.h>

#include <sys/types.h>

#include <sched.h>

#include <stdlib.h>

#include <unistd.h>


int main(void)

{

struct sched_param param;

int policy;

char *policy_name;


pid_t current_pid = getpid();

/*

only superuser may lower the priorities and change schedule

*/

sched_getparam(current_pid, &param);

param.sched_priority = 65;

sched_setscheduler(current_pid, SCHED_FIFO, &param);


sched_getparam(current_pid, &param);

policy = sched_getscheduler(current_pid);


if      (policy == 0) policy_name = "SCHED_OTHER";

else if (policy == 1) policy_name = "SCHED_FIFO";

else if (policy == 2) policy_name = "SCHED_RR";

else policy_name = "Unknown";

printf("Current PID: %d\n", (int)current_pid);

printf("Scheduling Policy: %d, %s\n", policy, policy_name );

printf("RT Sched Priority: %d  \n\n", param.sched_priority);


puts("#ps -l to check the priority");

sleep(100);


return 0;

}



# ./a.out &

[1] 12945

Current PID: 12945

Scheduling Policy: 1, SCHED_FIFO

RT Sched Priority: 65  


#ps -l to check the priority


# ps -l

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD

4 S     0 12893  1623  0  80   0 -  1535 wait   pts/0    00:00:00 bash

4 S     0 12945 12893  0  -6   - -   404 hrtime pts/0    00:00:00 a.out

4 R     0 12946 12893  0  80   0 -   625 -      pts/0    00:00:00 ps




+ Recent posts