부모 프로세스에서는 랜덤한 값을 생성하고 자식프로세스에서는
이를 더하는 프로그램을 만들려고 합니다.
fork()를 이용해서 자식프로세스를 생성을 하겠는데...
자식프로세스와 부모프로세스가 전역변수를 사용시에 데이터 공유가
안된다고 들었습니다.
이를 어떻게 해결해야 할지 모르겠습니다.
파이프, 메세지큐, 공유메모리 등을 이용하여 통신을 하셔야 될것같은데..
저도 초짜라...쩝
일단 쓰레드 못지 않게 같은 영역을 쓰고 읽을수 있는 공유메모리가
좋을텐데....이방법은 모든 임계영역에 대한 부분을 프로그래머가
담당해야 하죠. 세마포어랑 같이 쓰던가...파일락, 뮤텍스 등등 골치가
아파집니다. 간단한 부분이라면 메세지큐가 제일 편하지 않을까...
생각해봅니다.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int fd[2];
FILE *instream, *outstream;
int a,b,sum;
/*
srand(time(0));
a=rand();
b=rand();
위 함수들은 time.h, math.h, complex.h 를 include해야 쓸수 있다.
이와같이 하여 랜덤한 값을 가져올수 있다.
그러나 이와 같이하여 a+b를 구하게 되면 오버플로가 발생하여 정확한 합
을 구할수가 없다.
(가끔 랜덤한 수가 작은 수일때는 오버플로가 발생하지 않으므로 정확한
합이 나오기도 한다... 랜덤한 수를 일정범위 안에서 발생시킬수 있다면 좋
을텐데....) 테스트용으로 아래와 같이 a, b에 값을 직접 할당하여 테스트해 보았다.
*/
a=10; //랜덤하게 숫자를 얻는다.
b=20; //랜덤하게 다른 숫자 하나를 얻는다.
if(pipe(fd)==-1){ //파이프 생성
fprintf(stderr,"pipe() error\n");
return EXIT_FAILURE;
}
if((pid=fork())==-1){ //자식 프로세스 생성
fprintf(stderr,"fork() error\n"); //fork() 실패시 에러 출력하고
return EXIT_FAILURE; //프로그램을 종료한다.
}else if(pid==0){ //자식 프로세스가 처리할 코드부분이다. 합을 구해서 부모에게 전해준다
outstream=fdopen(fd[1],"w"); //파이프의 한쪽을 쓰기 모드로 열어놓고,
sum=a+b; //랜덤하게 생성된 두 값을 합해서 자식프로세스의 sum변수에 저장한다. 부모프로세스의 sum 변수값은 변하지 않는다.
fprintf(outstream,"%d\n",sum); // 합한 결과를 위에서 열어놓은 파이프에 쓰기를 수행함으로서 부모프로세스에게 전해준다.
fclose(outstream); //열어놓은 파일포인터를 닫는다.
return EXIT_SUCCESS; //자식 프로세스 종료
}else{ // 부모 프로세스가 처리할 코드부분이다. 자식프로세스에게서 합을 얻어온다.
instream=fdopen(fd[0],"r"); //파이프의 또다른 한쪽을 읽기 모드로 연다.
fscanf(instream,"%d",&sum); //파이프로부터 읽기를 수행함으로서 자식 프로세스가 전해준 합의 결과를 부모프로세스의 sum변수에 할당한다. 부모프로세스의 sum값이 변화한다.
fclose(instream);
}
fprintf(stdout,"%d = %d + %d\n",sum,a,b); //부모프로세스가 계속해서 수행하는 코드이다. 합의 결과를 화면 출력한다.
}
메세지큐나 공유메모리 세마포어..등등
글쎄요...프로세스끼리 통신하는 부분을 연계하셔야 될것 같은데요.
파이프, 메세지큐, 공유메모리 등을 이용하여 통신을 하셔야 될것같은데..
저도 초짜라...쩝
일단 쓰레드 못지 않게 같은 영역을 쓰고 읽을수 있는 공유메모리가
좋을텐데....이방법은 모든 임계영역에 대한 부분을 프로그래머가
담당해야 하죠. 세마포어랑 같이 쓰던가...파일락, 뮤텍스 등등 골치가
아파집니다. 간단한 부분이라면 메세지큐가 제일 편하지 않을까...
생각해봅니다.
막연한 저의 생각이니 믿지는 마세요.
SpeedBen
저같은 경우는 Unix socket 을 사용했습니다.
저같은 경우는 Unix socket 을 사용했습니다.
hi 용
screen71님의 말(IPC관하여 공부하시면)을 믿으심이 좋겠네요. ^
screen71님의 말(IPC관하여 공부하시면)을 믿으심이 좋겠네요. ^^;
그나저나 백수 언제 탈출하냐... ㅡㅡ; 배고파라.
쿨럭..저랑 같은 수업 혹시 들으시는 건 아닌지...-_-;;
S대 Y 교수님 운영체제 수업 아닌가요?
저도 같은 문제로 고민중입니다...ㅠㅠ
제가 보기엔 IPC가 가장 좋은 방법이고...socket은 부수적인
제가 보기엔 IPC가 가장 좋은 방법이고...
socket은 부수적인 방법이 아닐까 생각이 드네요...
제가보기엔...
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
이건 /...
문제만 놓고 생각을 하면 IPC를 사용하는게 가장 합리 적일겁니다.
그런데 조금 발전적으로 생각한다면, 유닉스 도메인이나 TCP, UDP등의 소켓 프로그램을 생각할 수 있겠네요.
부모와 자식이 나중에 다른 호스트로 분리되야 한다면 즉 서버 클라이언트 모델로 확장성을 고려해야하는
경우는 소켓쪽을 생각해야합니다.
너무 쓸데 없는 곳까지 생각하는 건 아닌지....
Do you think that's the air you are breathing now?
답변 감사합니다.^^
결국은 IPC를 이용해야 하는 거군요...
그나마 쉬운 방법이 메시지큐인것 같은데.. 그쪽으로 더 공부를 해야할것
같은 생각이 드는군요..^^;;
아.. 그리고 저도 S대 Y교수님 수업 맞아요..^^;;;
하드웨어수업만 듣다가 프로그램을 짤려니깐.. 정신이 하나도 없네요..
인생은 한번뿐~!!
파이프를 이용한 프로세스간 통신을 이용
감사합니당^^
파이프를 이렇게 이용하는 것이였군요..
궁금한게 하나 있는데..
fdopen은 무슨 함수 인가요?
fopen과 어떤점에서 차이가 있는지요?
인생은 한번뿐~!!
fdopen은 스트림으로 오픈합니다.
fd 값을 넣어주면 해당 fd의 스트림을 넘겨주죠.
FILE * <-> fd 를 왔다갔다 할때 사용합니다. 일반적으로 두개를 같이 사용하는 것은 좋지 않습니다. 따라서 종종 한종류, 저수준, 고수준 입출력을 분리해서 사용하므로 많이 보지는 못했을겁니다. 특수한 경우에만 사용합니다.
PS) 아참 fileno()도 함 보시죠. 위의 함수와 형제뻘입니다.
========================================
* The truth will set you free.
댓글 달기