OS로부터 자원을 할당받은 작업의 단위
우리가 windonw의 .exe나 mac의 .dmg 확장자를 프로그램이라고 부른다.
프로그램의 특징은 아래와 같다.
이제 우리가 위와 같은 특징을 가진 .exe(프로그램)을 클릭해서 실행한다면 실행하는 순간 파일은 컴퓨터 메모리에 올라가고 동적인 상태가 된다.
이 상태의 프로그램을 프로세스라고 한다.
즉 프로그램은 코드 파일이고, 그 코드 파일을 실행한 결과가 프로세스이다.
프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위
예전에는 프로그램의 실행을 한 개의 프로세스만 사용했다고 한다. 그런데 요즘에는 유튜브를 보면서 롤도 함께 해야하는 세상이다.
이런 문제를 해결하기 위해 개발자들은 이런 생각을 했다. '한 프로그램을 처리하기 위한 프로세스를 여러 개 만들면 안될까?' 그러나 이것은 불가능했다.
이유는 운영체제는 안정성을 위해 프로세스마다 할당된 메모리 내의 정보에만 접근할 수 있도록 제약을 걸었다. 이를 벗어나는 정보에 접근하면 에러가 발생한다.
이렇게 프로세스를 다중으로 만들 수는 없어 만들어낸 것이 프로세스보다 더 작은 실행 단위 개념인 스레드이다.
스레드의 특징은?
스레드는 프로세스와 다르게 스레드 간 메모리를 공유하며 작동한다. 스레드끼리 프로세스의 자원을 공유하며 프로세스 실행 흐름의 일부가 된다.
스레드는 프로세스의 코드에 정의된 절차에 따라 실행되는 특정한 수행 경로이다
프로세스들끼리 의사소통을 하는 것을 IPC라고 한다.
프로세스가 통신이 가능하다는 것은 서로 다른 프로세스가 데이터를 주고 받을 수 있다는 것이고, 컴퓨터 내부에서 효율적으로 정보를 주고 받기 위한 통신의 일종이다.
인터넷 통신을 IPC의 확장이라고 이해할 수 있다. (프로세스 사이의 통신이 서버-클라이언트 간 통신과 유사하기 때문이다.)
IPC 통신 중 하나이며, 통신을 위한 메모리 버퍼를 생성해서 프로세스가 데이터를 주고 받게끔 한다.
파이프의 특징
! 파이프의 특성 중 유의할 것은 fork() 함수에 의해 복사되지 않는다. 그래서 부모와 자식은 같은 프로세스를 가르키게 된다.
명령어의 결과는 표준 출력 방식인 모니터에 출력이 된다.
그러나 리다이렉션을 이용하면 명령의 출력을 변경할 수 있습니다.
또한 리다이렉션을 이용하여 파일에 기록도 할 수 있다.
기존 파일의 내용을 삭제하고 새로운 결과를 저장할 때는 >,
기존 파일의 내용 뒤에 결과를 추가할 때는 >>를 사용한다.
< or << : 입력 방향 재지정
> or >> : 출력 방향 재지정
> : 덮어쓰기
>> : 내용 뒤에 추가하기
예시
./pipex file1 cmd1 cmd2 file2
./pipex는 실행파일 이름일 것이고 file1, file2는 임의로 만든 파일명이다.
또한 cmd1 cmd2는 두 개의 명령어를 의미한다.
< infile ls -l | wc -l > outfile <예시 코드>
1. infile의 내용이 ls -l의 표준 입력으로 사용된다.
2. ls -l의 표준 출력(ls -l의 아웃풋)은 wc -l의 표준 입력으로 사용된다.
3. wc -l의 표준 출력은 outfile에 찍힌다.
infile ---> ls -l ---> wc -l ---> outfile
* * * *
<in> <out> <in> <out>
IPC 통신인 파이프를 생성하기 위한 함수
#include <unistd.h>
int pipe(int fd[2]);
파라미터
반환값
새로운 프로세스를 생성하는 함수
#include <unistd.h>
pid_t fork(void);
반환값
프로세스의 종료 상태를 반환하는 함수이다.
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *stat_loc, int options)
파라미터
반환값
존재하는 두 개의 파일 디스크립터를 복제하는 함수
#include <unistd.h>
int dup2(inf fd, int fd2)
파라미터
반환값
시스템 에러를 출력하는 함수
#include <stdio.h>
void perror(const char *str);
파라미터
파일의 접근 권한을 확인하는 함수
#include <unistd.h>
int access(const char *path, int mode);
파라미터
반환값
파일을 실행하는 함수
#include <unistd.h>
int execve(const char *path, char argv[], char envp[]);
파라미터
반환값
./pipex infile "ls -l" "wc -l" outfile
새로운 outfile3
int main(int argc, char **argv, char **envp)
{
int fd[2];
int infile;
int outfile;
pid_t pid;
infile = open(argv[1], O_RDONLY, 0777);
outfile = open(argv[4], O_RDWR | O_CREAT | O_TRUNC, 0777);
if (infile == -1 || outfile == -1)
error();
if (argc == 5)
{
if (pipe(fd) == -1)
error();
pid = fork();
if (pid == -1)
error();
if (pid == 0)
child_proc(argv, envp, fd, infile);
waitpid(pid, 0, 0);
parent_proc(argv, envp, fd, outfile);
}
return (0);
}