부모프로세스랑 자식프로세스 sharedmemory 이용..
#include
#include
#include
int main()
{
int pid;
int shmid;
char *shmaddr;
int status;
pid = fork();
if( pid != 0 )
{
shmid = shmget((key_t)5634, 1234, IPC_CREAT|0666); //get ID
shmaddr = (char*)shmat(shmid, 0, 0);
printf("process1: %d \n",pid);
strcpy(shmaddr, "sohn");
printf("process1 sent message sohn to sharedMemory\n");
shmctl(shmid, IPC_RMID, 0);
sleep(1);
}
else if (pid = 0)
{
printf("process2 will receive message within 3 sec\n");
shmid = shmget((key_t)5634, 1234, 0666);
shmaddr = shmat(shmid, 0, 0);
printf("process2 :%d\n", pid);
printf("MESSAGE:%s\n", shmaddr);
sleep(2);
}
else
{
printf(" fork failed \n");
}
}
실행하면 자식 프로세스가 먼저 실행 되버려서..ㅜㅜ
공유메모리를 이용해서 보여줘야 하는데.. 세마포어 써서..공유메모리 부모 , 자식 , 이런 순서로 돌아가게 보여 주게 .. 작성 좀
도와주십시오..ㅜㅜ 잘 안되네요
제 의견으로는...
<code></code> 태그를 쓰지 않고 붙여넣기 하셔서.. 코드가 깨져보이네요.
자식 프로세스가 먼저 실행되는 건 아닙니다, 경우에 따라서 parent process가 먼저 실행될 수도,
child process가 먼저 실행될 수도 있죠. (스케줄링 정책에 따라서 그때그때 달라요~~ >.<)
APUE 책을 보니(1판, 8.3절), sleep을 줘서 parent 혹은 child가 먼저 실행되도록 trick을 썼네요.
실용적인 목적의 코드라면 이렇게 sleep으로 delay 주는 것이 곤란할 수 있겠지만, 그렇지 않고 단순한 교육(?)적인 목적이라면 ^^; 가능한 방법 같습니다.
참고로 vfork를 쓰면 확실히 child가 먼저 실행되는 것이 보장됩니다. 하지만 vfork는 가급적
사용하지 말라고 합니다. COW(Copy on Write) 개념이 없던 시절에는 vfork가 유용했을지 모르겠지만,
요즘 OS는 내부적으로 이미 COW 개념을 사용하기 때문에 의미가 없죠. (참고 : http://kldp.org/HOWTO/html/Secure-Programs-HOWTO/avoid-vfork.html)
아무튼 편법이 아닌, 정석적으로 순서를 제어할 수 있는 방법이 있을지는 모르겠습니다.
개인적인 의견으로는 “최소한 linux는 Real time OS가 아니기 때문에 불가능하다.”에 한 표입니다.
딴지인지 모르겠으나
else if (pid = 0)
여기서 pid == 0 인 것 아닌지...
그리고 어차피 pid == 0 아니면 pid != 0 이니까
마지막의 else는 의미가 없는 것 아닌지요...
여하튼 코드를 보니 옛날에 숙제하던 생각이 나네요. 모의 OS 만들기...
저도 자식이 먼저 뜨더군요 ^^ 그래서 애먹었습니다...
음...
APUE(1판)를 조금 더 읽어보니 답이 나와 있었습니다.
190 페이지의 Program 8.1 에서는, child가 먼저 실행됨을 보장하기 위하여 parent에
sleep을 걸었습니다. (parent가 먼저 실행됨을 보장하기 위해서는 child에 sleep을 걸면 되겠죠)
그런데 이는 trick일 뿐이고, 제대로 구현하려면 ipc나 시그널을 이용하라고 합니다.
"8.8 Race Conditions" 절에서 이에 대한 자세한 설명이 나오네요. 구체적인 코드도 나와있는데,
1. pipe를 이용한 방법
Program 8.7 (205 page) + Program 14.2 (432 page)
2. signal을 이용한 방법
Program 8.7 (205 page) + Program 10.17 (308 page)
입니다. 이런 식으로 접근하면 다른 방법도 많이 있겠네요.
아, 그리고 위에 김영일 님이 지적해 주신 것처럼 fork는 다음과 같은 return 값을 갖습니다.
1. fork가 실패하였을 경우 : fork() < 0
2. child 일 경우 : fork() == 0
3. parent일 경우 : fork() == "만들어진 child 의 PID"
따라서 cloudstrife 님이 작성하신 코드는 fork()가 실패할 경우, 의도한대로 동작하지 않게 됩니다.
(물론 if (pid = 0) 도... 고쳐야 합니다.)
버퍼가 아니라 구조체로 잡아야....
부모가 shared memory를 만들때 1234 사이즈로 막연한 버퍼로 잡는다면 트릭을 쓸 수 밖에 없구요..
struct Q {
#define P_WRITTEN 1
char flag;
char data[1234];
}
이런식으로 구조체로 메모리를 잡아서 flag 부분에 부모가 쓸때까지 자식이 기다리는 식으로 하세요..
둘간에 계속 IPC를 한다면... flag를 추가해서 state machine을 구현하는 것도...
댓글 달기