thread 연습중에 이해가 안가는 부분이 있어 질문 올립니다.

study의 이미지

https://kingko.tistory.com/entry/Message-Queue%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-Thread-%EA%B0%84-%EB%A9%94%EC%8B%9C%EC%A7%80-%EC%A0%84%EB%8B%AC
를 보면서 thread 프로그래밍 연습을 하고 있었는데요.

좀 이해가 안가는 부분이 있어서 질문 올립니다.
위의 링크를 참고해서 아래와 같이 예제를 만들어 보고 있었습니다. (아직 완성된 건 아닌데요..)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <stdint.h>
  5 #include <pthread.h>
  6 #include <sys/ipc.h>
  7 #include <sys/msg.h>
  8 #include <sys/stat.h>
  9 #include <sys/types.h>
 10 #include <fcntl.h>
 11 #include <unistd.h>
 12
 13 #define MAX_THREAD 4
 14
 15 pthread_mutex_t mutex_lock;
 16 pthread_cond_t sync_cond;
 17
 18 struct _data {
 19    int32_t queue_num;
 20    int32_t msgtype;
 21    int32_t tid;
 22    char msg[256];
 23    int32_t size;
 24    key_t key_id;
 25 };
 26 typedef struct _data data_t;
 27
 28 struct _doc_info {
 29    int32_t tnum;     /* thread number */
 30    int32_t start;    /* start location of the document */
 31    int32_t end;      /* end location of the document */
 32    char name[80];    /* document file name */
 33    char keyword[20]; /* string to find from the file */
 34 };
 35 typedef struct _doc_info doc_info_t;
 36
 37 int32_t search_keyword(char *string, char *word)
 38 {
 39    char *search;
 40    const char delim[] = " -.,()\";:{}'+@/<>[]|!?#\n";
 41    int32_t ret;
 42    char *copy;
 43
 44    copy = strdup(string);
 45
 46    search = strtok(copy, delim);
 47    while (search != NULL)
 48    {
 49       search = strtok(NULL, delim);
 50       if (search != NULL)
 51       {
 52          ret = strncmp(word, search, strlen(word));
 53          if (ret == 0)
 54          {
 55             printf("Found!! [%s - %s : %d]\n", word, search, strlen(word));
 56             free(copy);
 57             return ret;
 58          }
 59       }
 60    }
 61
 62    free(copy);
 63    return -1;
 64 }
 65
 66 void *Tfunction(void *data)
 67 {
 68    data_t Data;
 69    doc_info_t *DocInfo;
 70    int32_t bsize;
 71    int32_t ret;
 72    int32_t readn = 0;
 73    char line[256];
 74    char *s_word;
 75    char *str;
 76    FILE *fp;
 77
 78    Data = *(data_t *)(data);
 79    DocInfo = (doc_info_t *)Data.msg;
 80
 81    bsize = DocInfo->end - DocInfo->start;
 82
 83    fp = fopen(DocInfo->name, "r");
 84    if (fp == NULL)
 85    {
 86       perror("file open error");
 87       exit(-1);
 88    }
 89
 90    lseek(fileno(fp), DocInfo->start, SEEK_SET);
 91
 92    pthread_mutex_lock(&mutex_lock);
 93    pthread_cond_signal(&sync_cond);
 94    pthread_mutex_unlock(&mutex_lock);
 95
 96    for (readn = 0 ; readn < bsize ; )
 97    {
 98       str = fgets(line, 256, fp);
 99       if (str == NULL)
100       {
101          break;
102       }
103       else
104       {
105          line[strlen(line)] = '\0';
106       }
107
108       ret = search_keyword(line, DocInfo->keyword);
109       if (ret == 0)  /* Found */
110       {
111          Data.queue_num = 1;
112          Data.msgtype = 1 << 1;
113          Data.size = 256;
114          strncpy(Data.msg, line, 256);
115          printf("Found!!! [%d] : %s\n", DocInfo->tnum, line);
116
117          ret = msgsnd(Data.key_id, (void *)&Data, sizeof(Data), IPC_NOWAIT);
118          if (ret < 0)
119          {
120             perror("msg send error");
121             break;
122          }
123       }
124       readn = readn + strlen(line);
125       sleep(1);
126    }
127
128    fclose(fp);
129 }
130
131 int32_t main(int32_t argc, char *argv[])
132 {
133    data_t Data;
134    doc_info_t DocInfo;
135    struct stat FileInfo;
136    pthread_t p_thread[MAX_THREAD];
137
138    int32_t fd = 0;
139    int32_t fsize = 0;
140    int32_t block_size = 0;
141    int32_t ret = 0;
142    char *fname;
143    char *search;
144    int32_t msg_type;
145    key_t key_id;
146    int32_t i;
147
148    pthread_mutex_init(&mutex_lock, NULL);
149    pthread_cond_init(&sync_cond, NULL);
150
151    fname = argv[1];
152    search = argv[2];
153
154    key_id = msgget((key_t)8888, IPC_CREAT | 0666);
155    if (key_id == -1)
156    {
157       perror("msgget error : ");
158       exit(0);
159    }
160
161    /* open a document file */
162    fd = open(fname, O_RDONLY);
163    if (fd < 0)
164    {
165       perror("File Open Error");
166       return -1;
167    }
168
169    ret = fstat(fd, &FileInfo);
170    if (ret < 0)
171    {
172       perror("fstat error");
173       return -1;
174    }
175    fsize = FileInfo.st_size;
176
177    block_size = fsize / MAX_THREAD;
178
179    for (i = 0 ; i < MAX_THREAD ; i++)
180    {
181       DocInfo.start = (i * block_size);
182       DocInfo.end = DocInfo.start + block_size;
183       sprintf(DocInfo.name, "%s", fname);
184       sprintf(DocInfo.keyword, "%s", search);
185       DocInfo.tnum = i;
186
187       if (i == (MAX_THREAD - 1))
188       {
189          DocInfo.end += fsize % MAX_THREAD;
190       }
191
192       Data.queue_num = 1;
193       Data.msgtype = 1 << 2;
194       Data.size = sizeof(DocInfo);
195       Data.key_id = key_id;
196       Data.tid = DocInfo.tnum;
197       memcpy((void *)Data.msg, (void *)&DocInfo, sizeof(DocInfo));
198
199       pthread_mutex_lock(&mutex_lock);
200       pthread_create(&p_thread[i], NULL, Tfunction, (void *)&Data);
201       pthread_cond_wait(&sync_cond, &mutex_lock);
202       pthread_mutex_unlock(&mutex_lock);
203    }
204
205    while(1)
206    {
207       ret = msgrcv(key_id, (void *)&Data, sizeof(Data), (1>>1), 0);
208       if (ret == -1)
209       {
210          perror("msg recv error");
211       }
212
213       printf("lines [%d] : %s\n", Data.tid, Data.msg);
214    }
215
216    return 0;
217 }

실행을 해보면 아래와 같이 됩니다.

$ ./a.out loglog localhost
Found!! [localhost - localhost : 9]
Found!!! [544109898] : Jun 14 20:36:30 localhost kernel: Linux version 4.18.0-240.el8.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)) #1 SMP Fri Sep 25 19:48:47 UTC 2020
 
Found!! [localhost - localhost : 9]
Found!!! [859451442] : 20:36:30 localhost kernel: BIOS-e820: [mem 0x0000000000100000-0x00000000bfeeffff] usable
 
lines [0] : Jun 14 20:36:30 localhost kernel: Linux version 4.18.0-240.el8.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)) #1 SMP Fri Sep 25 19:48:47 UTC 2020
 
lines [3] : 20:36:30 localhost kernel: BIOS-e820: [mem 0x0000000000100000-0x00000000bfeeffff] usable
 
Found!! [localhost - localhost : 9]
Found!!! [544109898] : Jun 14 20:36:30 localhost kernel: x86/fpu: x87 FPU will use FXSAVE
 
Found!! [localhost - localhost : 9]
Found!!! [544109898] : Jun 14 20:36:30 localhost kernel: BIOS-e820: [mem 0x000000000009f800-0x000000000009ffff] reserved
 
lines [1] : Jun 14 20:36:30 localhost kernel: x86/fpu: x87 FPU will use FXSAVE
 
lines [2] : Jun 14 20:36:30 localhost kernel: BIOS-e820: [mem 0x000000000009f800-0x000000000009ffff] reserved
 
Found!! [ - 14 : 0]
Found!!! [544109898] : Jun 14 20:36:30 localhost kernel: BIOS-e820: [mem 0x00000000bfef0000-0x00000000bfefefff] ACPI data
 
lines [3] : Jun 14 20:36:30 localhost kernel: BIOS-e820: [mem 0x00000000bfef0000-0x00000000bfefefff] ACPI data
 
Found!! [ - 14 : 0]
Found!!! [544109898] : Jun 14 20:36:30 localhost kernel: BIOS-provided physical RAM map:
 
lines [1] : Jun 14 20:36:30 localhost kernel: BIOS-provided physical RAM map:
 
Found!! [ - 14 : 0]
Found!!! [544109898] : Jun 14 20:36:30 localhost kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009f7ff] usable
 
lines [1] : Jun 14 20:36:30 localhost kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009f7ff] usable

실행예에서 Found!!! 다음에 DocInfo->tnum을 찍어보는데요.
이 값은 소스코드 185번째 줄에서 0, 1, 2, 3 중의 한 값으러 지정을 하는데, 어떻게 544109898 같은 값이 보이는지 이해가 안가서 질문을 올립니다.

혹시 제가 잘못이해하고 있는 부분이 보이시면, 코멘트 부탁드립니다.

라스코니의 이미지

DocInfo, Data가 main() 함수 내에 있고 (local variable), 각각의 쓰레드마다 값만 바꿔서 전달하는데 그 주소를 가지고 쓰레드에 전달하네요. 결국은 계속 바뀔수 밖에 없고 또 주소 자체가 스택 영역에 있기 때문에 별도의 스택 영역을 가지고 있는 쓰레드가 보면 의미없는 영역이 됩니다.

DocInfo, Data를 전역 변수로 선언하시고 DocInfo[Thread_num], Data[Thread_num] 등으로 바꿔서 접근해 보세요.

댓글 달기

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