|
ÃÑ ÆäÀÌÁö ¼ö : 3027
![]()
|
ÇöÀçÀ§Ä¡ : ¹Ì´Ï»çÀÌÆ®>Thread>Advanced>SendMessage 1 ¼Ò°³
¾²·¹µå ÇÁ·Î±×·¡¹ÖÀ» ÇÒ ¶§ °¡Àå ½Å°æ¾²ÀÌ´Â°Ç ¿ª½Ã ¾²·¹µåµ¿±âÈ¿Í ¾²·¹µå°£ ¸Þ½ÃÁö Àü´Þ°ú °ü·ÃµÈ ¹®Á¦ÀÏ °ÍÀÌ´Ù. ¶ÇÇÑ ¾²·¹µå°£ ¸Þ½ÃÁö Àü´Þ¿¡´Â ¾²·¹µå µ¿±âÈ ¹®Á¦±îÁö ÇÔ²² °í¹ÎÇØ¾ß ÇÑ´Ù. ÀÌ ¹®¼´Â ´ÙÁß¾²·¹µå¿¡¼ ¾²·¹µå°£ ¸Þ½ÃÁö¸¦ È¿°úÀûÀ¸·Î Àü´ÞÇϱâ À§ÇÑ ´Ù¾çÇÑ ¹æ¹ýµéÀ» ±â¼úÇÑ´Ù.
¿©±â¿¡¼ ¼Ò°³ÇÏ´Â ¹æ¹ýµéÀº ¼ö¸¹Àº ¹æ¹ýµé Áß ¸î°¡Áö ¹æ¹ýµéÀÏ »ÓÀÌ´Ù. ½ÇÁ¦ ÇÁ·ÎÁ§Æ®¿¡¼´Â ´Ù¾çÇÑ ÀÀ¿ëÀ» »ý°¢ÇØ¾ß ÇÒ °ÍÀÌ´Ù. 2 ½Ã³ª¸®¿À
¿µ¾î¹®¼¸¦ ÆÄ½ÌÇØ¼ TermÀ» ¾ò¾î¿À°í, ÃâÇöÇÑ TermÀÇ ºóµµ¼ö¸¦ °è¼öÇÏ´Â ÇÁ·Î±×·¥À» ¸¸µéµµ·Ï ÇϰڴÙ. ºü¸¥ ÆÄ½ÌÀ» À§Çؼ, ¹®¼°¡ ÁÖ¾îÁö¸é ¹®¼¸¦ ¶óÀμö¸¦ ±âÁØÀ¸·Î 4µîºÐ ÇÑ´ÙÀ½, 4°³ÀÇ ¾²·¹µå¸¦ µ¹·Á¼ º´·Ä·Î ó¸®Çϵµ·Ï ÇÒ °ÍÀÌ´Ù. ÀÌ ÇÁ·Î±×·¥Àº ´ÙÀ½ÀÇ »çÇ×À» ¸¸Á·½ÃÄÑ¾ß ÇÑ´Ù.
3 ±¸Çö¹æ¾È
´ÙÀ½Àº ¹®¼¸¦ ÆÄ½ÌÇØ¼ <Term, count>¸¦ ¾ò¾î¿À´Â ÇÁ·Î±×·¥ÀÌ´Ù. ´ÜÀÏ ¾²·¹µå·Î ÀÛµ¿ÇÏ´Â ÇÁ·ÎÅäŸÀÔÀÇ ÇÁ·Î±×·¥À¸·Î ¾Æ·¡ÀÇ Äڵ带 ¸ÖƼ¾²·¹µå¹æ½ÄÀ¸·Î ¼öÁ¤ÇÒ °ÍÀÌ´Ù. #include <sys/types.h> #include <regex.h> #include <string.h> #include <stdio.h> #include <errno.h> #include <vector> #include <string> #include <iostream> #include <fcntl.h> using namespace std; /* * ÁÖ¾îÁø ¹®¼¿¡¼ ´Ü¾î¸¦ ¾ò¾î¿Â´Ù. * ÀÔ·ÂµÈ ¶óÀÎÀº strtok¸¦ ÅëÇØ¼ ÅäÅ«À¸·Î ¸ÕÀú ºÐ¸®µÇ°í * ºÐ¸®µÈ ¹®ÀÚ¿Àº Á¤±ÔÇ¥ÇöÀ» ¸¸Á·Çϸé TermÀ¸·Î ÆÇ´ÜÇϰí Ãâ·ÂÇÑ´Ù. * ½ÇÇàÀÎÀÚ : Á¤±ÔÇ¥Çö½Ä * »ç ¿ë ¿¹ : */ int main(int argc, char **argv) { FILE *fp; int rtv; regex_t preg; char linebuf[1024]; char *tr; char seps[] = " -.,()\";:{}'+@/<>[]|!?#"; char msg[64]; int i; vector<string> FileList; // ÆÄ½ÌÇÒ ÆÄÀÏÀ» µî·ÏÇÑ´Ù. FileList.push_back("rfc.dat"); if (argc != 2) { printf("Usage : %s [pattern]\n", argv[0]); return 1; } // Á¤±ÔÇ¥ÇöÀ» À§ÇÑ ÄÄÆÄÀÏ·¯ »ý¼º rtv = regcomp(&preg, argv[1], REG_EXTENDED|REG_NOSUB); if(rtv != 0) { regerror(rtv, &preg, NULL, 0); return 1; } for(int i = 0; i < FileList.size(); i++) { fp = fopen(FileList[i].c_str(), "r"); if (fp == NULL) { perror("Error "); return 1; } while(fgets(linebuf, 1024, fp) != NULL) { linebuf[strlen(linebuf)-1] = '\0'; // ÅäÅ«À¸·Î ±¸ºÐÇÑ´ÙÀ½ tr = strtok(linebuf, seps); while(tr != NULL) { tr = strtok(NULL, seps); if (tr != NULL) { // Á¤±ÔÇ¥ÇöÀ» ¸¸Á·ÇÏ´ÂÁö È®ÀÎÇÑ´Ù. if (regexec(&preg, tr, 0, NULL, 0) == 0) { cout << "Find Term : " << tr << endl; } } } } fclose(fp); } }´ÙÀ½°ú °°ÀÌ ½ÇÇàÇÏ¸é µÈ´Ù. # ./getterm "[a-zA-Z0-9]" 3.1 ¸Þ½ÃÁöÅ¥ ±¸Çö
¸Þ½ÃÁöÅ¥ ±¸Çö¿¡ ´ëÇÑ ¾ÆÀ̵ð¾î´Â ´ÙÀ½°ú °°´Ù.
![]() 3.1.1 worker Thread °ü¸®
ÁÖ°í ¹Þ´Â µ¥ÀÌÅÍ¿¡ ŸÀÔÀ» µÎ¾î¼ °ü¸®Çϵµ·Ï ÇÒ °ÍÀÌ´Ù. struct Data
{
int type;
char *Data;
int size;
};
Type´Â ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ ÇÒ °ÍÀÌ´Ù.
3.1.2 ¾²·¹µå µ¿±âÈ
¾²·¹µå°£ µ¿±âÈ´Â mutex Àá±Ý°ú Á¶°Çº¯¼ö¸¦ ÀÌ¿ëÇÒ °ÍÀÌ´Ù. 3.1.3 ÇÁ·Î½ÃÁ®
´ëÃæ ±×¸²À» ±×·Á¾ß Äڵ尡 ¸¸µé¾î Áö´Â ½ºÅ¸ÀÏÀ̶ó¼... main
{
»ý¼º ¾²·¹µå °¹¼ö´Â 4°³·Î ÇÑ´Ù.
¹®¼¸¦ Àоîµé¿©¼ ¹®¼ÀÇ Line¼ö¸¦ °è¼öÇÑ´Ù.
¸Þ½ÃÁöÅ¥¸¦ »ý¼ºÇÑ´Ù.
for(i = 0; i < 4; i++)
{
// ¾²·¹µå µ¿±âÈ Start
Worker ¾²·¹µå¸¦ »ý¼ºÇÑ´Ù. ÀÎÀÚ·Î ¹®¼ÀÇ OffsetÁ¤º¸¸¦ ³Ñ±ä´Ù.
¾²·¹µå ÇÔ¼ö¸íÀº WThread·Î ÇÑ´Ù.
// ¾²·¹µå µ¿±âÈ End
}
¸ÞÀÎ ¾²·¹µå¸¦ ¼öÇàÇÑ´Ù.
while(1)
{
¸Þ½ÃÁö Å¥·ÎºÎÅÍ µ¥ÀÌÅ͸¦ Àд´Ù.
switch(µ¥ÀÌÅÍ Å¸ÀÔ)
case ÀϹݵ¥ÀÌÅÍ
{
TermÀ» °è¼öÇÑ´Ù.
}
case Á¦¾îµ¥ÀÌÅÍ
{
Á¾·á·çƾÀ» ¼öÇàÇÑ´Ù.
¸ðµç ¾²·¹µå°¡ ÀÛ¾÷À» Á¾·áÇß´Ù¸é, Break;
}
}
<Term,Count>°á°ú¸¦ Ãâ·ÂÇÑ´Ù.
}
3.1.4 ÄÚµå ±¸Çö ¹Ì¿Ï¼º ÄÚµå´Ù. g++ ·Î ÄÄÆÄÀÏ Çϸé, ¸Þ½ÃÁöÅ¥¸¦ ÅëÇØ¼ worker thread¿¡¼ main thread·Î ºÐ¼®µÈ TermÀÌ Àü´ÞµÇ´Â°É È®ÀÎÇÒ ¼ö ÀÖ´Ù. ¸Þ½ÃÁöÅ¥¸¦ ÅëÇÑ µ¥ÀÌÅÍ Åë½ÅÀÇ ±âº»ÀûÀÎ ±¸ÇöÀº ³¡³µ´Ù°í º¼ ¼ö ÀÖ´Ù. Äڵ带 Á»´õ ±ò²ûÇÏ°Ô Çϰí, ¸î ±ºµ¥ ¿¹¿Ü󸮸¦ ÇØÁÖ¾î¾ß ÇÑ´Ù. #include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <regex.h>
#include <fcntl.h>
#include <string.h>
#define ThreadNum 4
pthread_mutex_t mutex_lock;
pthread_cond_t sync_cond;
pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;
const char seps[] = " -.,()\";:{}'+@/<>[]|!?#\n"; // Token
// ÁÖ°í ¹ÞÀ» µ¥ÀÌÅÍ
struct Data
{
int queuenum;
int msgtype;
int tid;
char msg[256];
int size;
key_t key_id;
};
// worker ¾²·¹µå¿¡ ³Ñ°ÜÁÙ Á¤º¸
struct DocInfo
{
int tnum; // thread id
int start; // ¹®¼½ÃÀÛ À§Ä¡
int end; // ¹®¼ ³¡ À§Ä¡
char fname[80]; // ÀÛ¾÷ ÆÄÀϸí
char regex[24]; // Á¤±ÔÇ¥Çö ¹®ÀÚ¿
};
/*
* worker ¾²·¹µå ÇÔ¼ö
*/
void *Tfunction(void *data)
{
struct Data lData;
struct DocInfo *lDocInfo;
FILE *fp;
char line[256];
int rtv;
int bsize;
int readn = 0;
regex_t preg;
char *tr;
lData = *(struct Data *)(data);
lDocInfo = (struct DocInfo *)lData.msg;
bsize = lDocInfo->end - lDocInfo->start;
printf("DEBUG Thread %d %d\n", lDocInfo->tnum, bsize);
if((fp = fopen(lDocInfo->fname, "r")) == NULL)
{
perror("Fopen Error");
exit(0);
}
lseek(fileno(fp), lDocInfo->start, SEEK_SET);
rtv = regcomp(&preg, lDocInfo->regex, REG_EXTENDED|REG_NOSUB);
pthread_mutex_lock(&mutex_lock);
pthread_cond_signal(&sync_cond);
pthread_mutex_unlock(&mutex_lock);
if (rtv != 0)
{
regerror(rtv, &preg, lDocInfo->regex, REG_EXTENDED|REG_NOSUB);
exit(0);
}
for (readn = 0; readn < bsize; )
{
if(fgets(line, 256, fp) == NULL)
break;
tr = strtok(line, seps);
if (tr != NULL)
{
if (regexec(&preg, tr, 0, NULL, 0) == 0)
{
lData.queuenum = 1;
lData.msgtype = 1 << 1;
lData.size = strlen(tr);
sprintf(lData.msg, "%s", tr);
if(msgsnd(lData.key_id, (void *)&lData, sizeof(lData), IPC_NOWAIT) <0)
{
perror("msg snd error");
exit(0);
}
}
}
readn += strlen(line);
sleep(1);
}
// Á¾·á ¸Þ½ÃÁö¸¦ º¸³½´Ù.
}
int main(int argc, char **argv)
{
struct Data lData;
struct DocInfo lDocInfo;
pthread_t p_thread[ThreadNum];
int fd;
char *fname;
int fsize = 0;
int blocksize = 0;
struct stat fileinfo;
char *regex;
// Message queue
key_t key_id;
int msgtype;
fname = argv[1];
regex = argv[2];
// ¸Þ½ÃÁöÅ¥ »ý¼º
key_id = msgget((key_t)8888, IPC_CREAT|0666);
if (key_id == -1)
{
perror("msgget error : ");
exit(0);
}
// Open File
fd = open(fname, O_RDONLY);
if (fd < 0)
{
perror("Open file error");
return 1;
}
if(fstat(fd, &fileinfo)< 0)
{
return 1;
}
fsize = fileinfo.st_size;
printf("T Size is %d\n", fsize);
blocksize = fsize / ThreadNum;
for (int i = 0; i < ThreadNum; i++)
{
lDocInfo.start = (i*blocksize);
lDocInfo.end = lDocInfo.start+blocksize;
sprintf(lDocInfo.fname, "%s", fname);
sprintf(lDocInfo.regex, "%s", regex);
lDocInfo.tnum = i;
if (i == (ThreadNum -1))
lDocInfo.end += fsize%ThreadNum;
lData.queuenum = 1;
lData.msgtype = 1 << 2;
lData.size = sizeof(lDocInfo);
lData.key_id = key_id;
lData.tid = lDocInfo.tnum;
memcpy((void *)lData.msg, (void *)&lDocInfo, sizeof(lDocInfo));
pthread_mutex_lock(&mutex_lock);
pthread_create(&p_thread[i], NULL, Tfunction, (void *)&lData);
pthread_cond_wait(&sync_cond, &mutex_lock);
pthread_mutex_unlock(&mutex_lock);
}
while(1)
{
if(msgrcv(key_id, (void *)&lData, sizeof(lData), (1 >> 1), 0) == -1)
{
perror("msgrcv error: ");
}
printf("Get Term %d %s\n", lData.tid, lData.msg);
}
}
4 °øÀ¯¸Þ¸ð¸® ±¸Çö
°øÀ¯¸Þ¸ð¸®´Â Ä¿³Î¿¡ ¸Þ¸ð¸® °ø°£À» ÇÒ´çÇÔÀ¸·Î½á, ½Ã½ºÅÛ Àü¿ªÀûÀ¸·Î ÀÚ¿øÀ» »ç¿ëÇÒ ¼ö ÀÖµµ·Ï Áö¿øÇÏ´Â IPC ¼³ºñÁß Çϳª´Ù. ÀÌ·¯ÇÑ Æ¯¼ºÀ» ÀÌ¿ë ¾²·¹µå°£ ¸Þ½ÃÁö ±³È¯Àº °øÀ¯¸Þ¸ð¸®»ó¿¡ ȯÇüÅ¥¸¦ ¸¸µå´Â °ÍÀ¸·Î ±¸Çö°¡´ÉÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
ÀÌ È¯ÇüÅ¥¿¡´Â ¿©·¯°³ÀÇ ¾²·¹µå°¡ Á¢±ÙÀ» ÇÏ°Ô µÉ °ÍÀ̹ǷÎ, ¾²·¹µå°£ µ¿±âȰ¡ Çʼö ÀûÀϰǵ¥, mutex°¡ ¾Æ´Ñ ·¹ÄÚµå Àá±ÝÀ¸·Îµµ ¾²·¹µå°£ Á¢±ÙÁ¦¾î¸¦ ÇÒ ¼ö ÀÖ´Ù. ·¹ÄÚµå Àá±ÝÀ» ÅëÇØ¼ ¾²·¹µåµ¿±âȸ¦ Á¦¾îÇÏ´Â ¹æ¹ýÀº °øÀ¯¸Þ¸ð¸®¿Í ÆÄÀÏÀá±ÝÀ» ÀÌ¿ëÇÑ ÇÁ·Î¼¼½º°£ µ¥ÀÌÅÍ °øÀ¯¿¡¼ ÀÌ¹Ì ´Ù·é¹Ù°¡ ÀÖ´Ù.
¾µ¸¸ÇÑ ¿¹Á¦¶ó°í »ý°¢Àº ÇÏÁö¸¸ À̹ø ±¸Çö¿¡ ±×´ë·Î Àû¿ëÇϱ⿡´Â ¼º°ÝÀÌ ´Ù¸£´Ù. À̹ø ±¸ÇöÀº ¿©·¯°³ÀÇ »ý»êÀÚ¿Í ÇϳªÀÇ ¼ÒºñÀÚ°¡ Á¸ÀçÇÏ´Â Çü½ÄÀ̱⠶§¹®ÀÌ´Ù. ¹¹ ±×·¸´Ù°í Å©°Ô ¹®Á¦µÉ°Ç ¾ø´Ù. ¾Æ·¡¿Í °°ÀÌ »ý»ê/¼ÒºñÀÚ ¹æ½ÄÀ» ¾à°£ ¼öÁ¤ÇÏ´Â °ÍÀ¸·Î ÇØ°áÃ¥À» »ï¾Ò´Ù. ![]()
¾²·¹µå°£ µ¿±âÈ´Â ±×´ë·Î ÆÄÀÏÀÇ ·¹ÄÚµå Àá±ÝÀ» ÀÌ¿ëÇÒ °ÍÀÌ´Ù. ÀÌ °æ¿ì ´Ù¼öÀÇ »ý»êÀÚ¸¦ Á¦¾îÇØ¾ß Çϴµ¥, óÀ½ 8 byte¸¦ »ý»êÀÚ°£ Á¢±ÙÁ¦¾î¸¦ À§ÇÑ Àá±ÝÀ¸·Î »ç¿ëÇÒ °ÍÀÌ´Ù. óÀ½ ·¹Äڵ忡 ´ëÇÑ »ý»êÀÚ¸¸ÀÌ ·¹Äڵ忡 Å¥(»¡°£»ö)¿¡ ¾µ±ÇÇÑÀ» °¡Áö°Ô µÈ´Ù.
µ¥ÀÌÅÍ ¾²±â ±ÇÇÑÀ» ¾òÀº ¾²·¹µå´Â °øÀ¯¸Þ¸ð¸®¿¡ µ¥ÀÌÅ͸¦ ¾²°í, ÇØ´ç °øÀ¯¸Þ¸ð¸®¿¡ ´ëÀÀµÇ´Â ·¹Äڵ忡 Àá±ÝÀ» Ç®°ÔµÈ´Ù. ±×·¯¸é ¼ÒºñÀÚ´Â Àá±ÝÀ» ¾ò°í, Àá±Ý¿¡ ´ëÀÀµÇ´Â °øÀ¯¸Þ¸ð¸®¸¦ ã¾Æ°¡¼ Á¤º¸¸¦ Àоî¿À¸é µÈ´Ù. ¿¹Á¦·Î Á¦½ÃÇÑ ¹®¼¸¦ ÀÌÇØÇϰí ÀÖ´Ù¸é, À§ÀÇ ¹æ½ÄÀ¸·Î ¼öÁ¤ÇÏ´Â°Ç ±×¸® ¾î·ÆÁö ¾ÊÀ» °ÍÀÌ´Ï, ±»ÀÌ Äڵ带 ¸¸µéÁø ¾Êµµ·Ï ÇϰڴÙ.
|
|||||