message queue 사용에 있어서 질문~~

arosis의 이미지


안녕하세요.
메시지큐 사용에 있어서 질문이 있어서 이렇게 글 올립니다.
결론부터 말씀드리면 메시지큐를 사용하여 포인터를 넘기게 되면 포인터가 가르키는 값이 변형된다는 문제입니다.
아래 결과값에 찍힌 -1079702760은 확인해본 결과 some의 주소값입니다. (send app의 &bb와 같은 값입니다.)
주소값은 제대로 넘어왔지만 주소값을 까보니 자기 주소가 들어있네요. 쩝....

하루종일 삽질하다가 질문 올립니다. 우매한 저에게 명쾌한 답을 주시면 감사하겠습니다. ㅠ.ㅠ
아무리 샘플들이나 글들을 찾아봐도 포인터를 넘기는 예제나 글귀는 없네요.
메시지큐를 이용해서 포인터를 넘길 수 없는건가요??
아니면 뭔가 제가 모르는 메시지큐의 메카니즘이 있는걸까요....
혹시 이 부분에 대해서 알고 계시는 고수분이 계시면 답변 꼭 좀 부탁드립니다.

- 결과값 -
[Send App] my_msg_type : 1
[Send App] a : 2
[Send App] *some : 3
[Receive App] my_msg_type : 1
[Receive App] a : 2
[Receive App] *some : -1079702760

- SEND APPLICATION EXAMPLE -

#include
#include
#include
#include

#include
#include
#include

struct temp_struct
{
int a;
int *some;
};

struct my_msg_st
{
long int my_msg_type;
struct temp_struct my_msg_struct;
};

int main()
{
struct my_msg_st some_data;

int msgid;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);

if (msgid == -1)
{
fprintf(stderr, "[Send App] msgget failed with error: \n");
exit(EXIT_FAILURE);
}

some_data.my_msg_type = 1;
some_data.my_msg_struct.a = 2;
int bb = 3;
some_data.my_msg_struct.some = &bb;

printf("[Send App] my_msg_type : %d\n",some_data.my_msg_type);
printf("[Send App] a : %d\n",some_data.my_msg_struct.a);
printf("[Send App] *some : %d\n",*some_data.my_msg_struct.some);

if (msgsnd(msgid, &some_data, 1000, 0) == -1) // size는 임시로 1000으로 잡았습니다.
{
fprintf(stderr, "msgsnd failed\n");
exit(EXIT_FAILURE);
}

return 1;
}

- RECEIVE APPLICATION EXAMPLE -

#include
#include
#include
#include

#include
#include
#include

struct temp_struct
{
int a;
int *some;
};

struct my_msg_st
{
long int my_msg_type;
struct temp_struct my_msg_struct;
};

int main(int argc, char **argv)
{
int msgid;
struct my_msg_st some_data;
long int msg_to_receive = 0;

msgid = msgget((key_t)1234, 0666 | IPC_CREAT);

if (msgid == -1)
{
fprintf(stderr, "[Receive App] msgget failed with error!!\n");
exit(EXIT_FAILURE);
}

if (msgrcv(msgid, &some_data, 1000, msg_to_receive, 0) == -1)
{
fprintf(stderr, "[Receive App] msgrcv failed with error\n");
exit(EXIT_FAILURE);
}

printf("[Receive App] my_msg_type : %d\n",some_data.my_msg_type);
printf("[Receive App] a : %d\n",some_data.my_msg_struct.a);
printf("[Receive App] *some : %d\n",*some_data.my_msg_struct.some);

if (msgctl(msgid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "msgctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}

return 1;
}

totohero의 이미지

고수는 아니고 코드도 들여다보지 않았지만 서로 다른 어플끼리 포인터값만 주고받으면 당연히 안되지요 --; 포인터가 가리키는 물리 메모리가 (커널 메모리나 공유 메모리가 아닌 이상) 프로세스마다 다를테니까요.

philnet의 이미지

프로세스마다 고유한 (가상) memory space를 가지고 있기 때문에, 하나의 응용 프로그램에서 할당된 포인터 값을 보내봐야, 다른 응용 프로그램에서는 의미가 없을 테지요.

따라서 2개 이상의 응용 프로그램들이 message queue를 통해 데이터를 주고 받을 때에는 항상 포인터가 아닌 데이터 값 자체를 복사해서 주고 받아야 합니다.

하지만, 크기가 큰 데이터를 아주 빈번하게 주고 받아야 해기 때문에, message queue를 통해 복사로 인해, 시스템에 과부하를 주는 경우라면, 공유 메모리(shared memory)를 사용해서 포인터를 전달할 수도 있긴 합니다.

즉, 공유될 데이터를 생성하는 응용 프로그램(send app)에서 공유 메모리를 create 합니다. 이후, 공유될 데이터를 공유 메모리에다 할당하고, 공유될 데이터의 address값에서 그 공유 메모리의 base address 값을 뺀 차이(offset) 값을 다른 응용 프로그램(recv app)에게 전달하는 겁니다. 그러면 recv app는 동일한 공유 메모리를 열어서 공유 메모리의 base address 값을 구하고, 거기에 전달받은 offset 값을 더해서 원하는 공유 데이터에 접근할 수 있습니다.

해당 공유 데이터를 하나의 app가 사용하는 동안, 다른 app가 이를 free 하거나 의미 없는 값으로 바꾸는 등과 같이 무효화시킨다면, seg. fault 와 같은 예측할 수 없는 일이 일어날 수 있으니 아주 정교한 제어 메카니즘이 필요할 것입니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.