부모프로세스랑 자식프로세스 sharedmemory 이용..

cloudstrife의 이미지

#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");
}

}

실행하면 자식 프로세스가 먼저 실행 되버려서..ㅜㅜ

공유메모리를 이용해서 보여줘야 하는데.. 세마포어 써서..공유메모리 부모 , 자식 , 이런 순서로 돌아가게 보여 주게 .. 작성 좀

도와주십시오..ㅜㅜ 잘 안되네요

silverjh2의 이미지

<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 만들기...
저도 자식이 먼저 뜨더군요 ^^ 그래서 애먹었습니다...

silverjh2의 이미지

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을 구현하는 것도...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.