ÃÑ ÆäÀÌÁö ¼ö : 3224
![]()
|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
![]()
Tweet
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù. °³ ¿ä
³ª´Â OOP¸¦ ÁÁ¾ÆÇÑ´Ù. °¢ ±â´ÉµéÀ» °´Ã¼ÈÇØ¼ ¼Ó¼º°ú ÇàÀ§·Î Ç¥ÇöÇÏ¿© °´Ã¼°£ÀÇ °ü°è·Î¼ ÇÁ·Î±×·¥À» ¿Ï¼º½ÃÄÑ ³ª°£´Ù´Â ±× °³³äÀÌ ÁÁ´Ù. ±×·± ÀÌÀ¯¿¡¼ ³ª´Â ±ò²ûÇÏ°Ô ¼³°è°¡ Àß µÈ ÀÚ¹Ù¸¦ Âü ÁÁ¾ÆÇÑ´Ù. ¹°·Ð C/C++ ¸¦ ºñ·ÔÇØ¼ Python, Perl, PHP, JavaScript, ... µéµµ ´Ù ÁÁ¾ÆÇϱä ÇÏ´Ù. µÑ¸¸ ²Å¾Æ¶ó¸é ´ç¿¬È÷ C++ (POSIX) °ú Java°¡ µÇ°Ú´Ù. C++·Î OOP¸¦ ÇÏ´Ùº¸¸é ¸ÖƼ¾²·¹µå ÇÁ·Î±×·¥¿¡¼ ¿ì¸®´Â ¾²·¹µå Ŭ·¡½ºÀÇ Çʿ伺À» Á¾Á¾ ´À³¤´Ù. ¾ÆÁÖ ¿¹Àü¿¡ ¾²·¹µå°´Ã¼¶ó°í ±âÃÊÀûÀΠŬ·¡½º¸¦ ¸¸µé¾î ¿©±â¿¡ ¿Ã¸°ÀûÀÌ ÀÖ´Ù. ÀÌÁ¦ ´Ù½Ã ÀÚ¹ÙÀÇ ±×°Í°ú °°Àº ±â´ÉÀ» ÇÏ´Â (¾ÆÁÖ ¾à°£ÀÇ Â÷ÀÌ´Â ÀÖÁö¸¸), ±×¸®°í ÁÖ·Î »ç¿ëµÇ´Â ¸Þ¼Òµå¸¸ ³ÖÀº ¾²·¹µå Ŭ·¡½º¸¦ ´Ù½Ã ¸¸µé¾î ¿Ã¸°´Ù. À̰ÍÀº ³ªÀÇ »ó¿ë ÇÁ·ÎÁ§Æ®¿¡¼µµ »ç¿ëµÇ´Â ¼öÁØÀÇ °ÍÀÌ¸ç ¿©·¯ºÐµéµµ ÀÚÀ¯·Ó°Ô »ç¿ë ¹× ¹ßÀü½Ãų ¼ö ÀÖ°Ú´Ù..
Ưº°È÷ ÀÚ¹Ù¿¡¼ isInterrupted() ¶õ ¸Þ¼Òµå´Â ¾²·¹µå¿¡¼ InterruptedException ÀÌ ¹ß»ýÇϰí À̸¦ catchÇÏÁö ¾Ê°í ±×³É Á¾·áµÇ¾úÀ»¶§ true¸¦ ¸®ÅÏÇϰí catchÇÏ¿´À»¶§´Â false¸¦ ¸®ÅÏÇÔÀ» ÁÖ¸ñÇÏÀÚ. ±×¸®°í ÀÌ Å¬·¡½º¿¡¼µµ µ¿ÀÏÇÏ°Ô µ¿ÀÛÇÑ´Ù. ¶ÇÇÑ, Çѹø Á¾·áµÈ ¾²·¹µå´Â ´Ù½Ã start½Ãų ¼ö ¾øÀ¸¸ç ÀÌ ¶ÇÇÑ µ¿ÀÏÇÏ°Ô ±¸ÇöµÇ¾ú´Ù. Code
#ifndef THREAD_H_
#define THREAD_H_
#include <pthread.h>
#include <string>
#include <stdexcept>
using namespace std;
class Thread
{
public:
Thread();
Thread(const string& name);
virtual ~Thread();
void start();
void join();
void join(unsigned long time);
void interrupt();
bool isInterrupted();
bool isAlive();
const string& getName();
void setName(const string& name);
private:
int _state;
bool _joinning;
bool _isInterrupted;
pthread_mutex_t _mutex;
pthread_cond_t _cond;
static pthread_attr_t _attr;
pthread_t _thread;
static long _id;
string _name;
static void* threadHandler(void* arg);
static void interruptHandler(int sigInt);
void init(const string& name);
virtual void run() = 0;
};
class InterruptedException : public exception
{
public:
explicit InterruptedException(const string& message)
: _message(message)
{}
virtual ~InterruptedException() throw()
{}
virtual const char* what() const throw()
{
return _message.c_str();
}
private:
string _message;
};
class IllegalThreadStateException : public exception
{
public:
explicit IllegalThreadStateException(const string& message)
: _message(message)
{}
virtual ~IllegalThreadStateException() throw()
{}
virtual const char* what() const throw()
{
return _message.c_str();
}
private:
string _message;
};
#endif /*THREAD_H_*/
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <signal.h> #include "Thread.h" using namespace std; long Thread::_id = 0; pthread_attr_t Thread::_attr; void* Thread::threadHandler(void* arg) { signal(SIGUSR1, interruptHandler); Thread* thread = (Thread*) arg; try { thread->run(); } catch (InterruptedException& e) { thread->_isInterrupted = true; } catch (...) { } thread->_state = -1; if (thread->_joinning) { pthread_mutex_lock(&thread->_mutex); pthread_cond_broadcast(&thread->_cond); pthread_mutex_unlock(&thread->_mutex); } return NULL; } void Thread::interruptHandler(int sigInt) { throw InterruptedException("Thread interrupted"); } Thread::Thread() { char name[32]; sprintf(name, "Thread-%ld", _id); init(name); } Thread::Thread(const string& name) { init(name); } Thread::~Thread() { pthread_attr_destroy(&_attr); pthread_mutex_destroy(&_mutex); pthread_cond_destroy(&_cond); } void Thread::init(const string& name) { _name = name; _joinning = false; _isInterrupted = false; pthread_mutex_init(&_mutex, NULL); pthread_cond_init(&_cond, NULL); _state = 0; pthread_mutex_lock(&_mutex); if (_id == 0) { pthread_attr_init(&_attr); pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED); } _id++; pthread_mutex_unlock(&_mutex); } void Thread::start() { if (_state == 1) { throw IllegalThreadStateException("Thread already started"); } else if (_state == 0) { _state = 1; pthread_create(&_thread, &_attr, threadHandler, this); } else if (_state == -1) { throw IllegalThreadStateException("Thread had been started"); } } void Thread::join() { if (_state == 1) { pthread_mutex_lock(&_mutex); _joinning = true; pthread_cond_wait(&_cond, &_mutex); _joinning = false; pthread_mutex_unlock(&_mutex); } } void Thread::join(unsigned long time) { if (_state == 1) { struct timeval now; struct timespec timeout; gettimeofday(&now, NULL); ldiv_t t = ldiv(time * 1000000, 1000000000); timeout.tv_sec = now.tv_sec + t.quot; timeout.tv_nsec = now.tv_usec * 1000 + t.rem; pthread_mutex_lock(&_mutex); _joinning = true; pthread_cond_timedwait(&_cond, &_mutex, &timeout); _joinning = false; pthread_mutex_unlock(&_mutex); } } void Thread::interrupt() { pthread_kill(_thread, SIGUSR1); } bool Thread::isInterrupted() { return _isInterrupted; } bool Thread::isAlive() { return _state == 1; } const string& Thread::getName() { return _name; } void Thread::setName(const string& name) { _name = name; }
* Test
#include <iostream>
#include "Thread.h"
using namespace std;
class Test1 : public Thread
{
private:
void run()
{
string name = getName();
for (int i = 0; i < 10; i++)
{
try
{
cout << name << endl;
sleep(1);
}
catch (InterruptedException& e)
{
cout << name << ": " << e.what();
cout << " but continue" << endl;
}
}
cout << name << " ending" << endl;
}
};
class Test2 : public Thread
{
private:
void run()
{
string name = getName();
for (int i = 0; i < 10; i++)
{
cout << name << endl;
sleep(1);
}
cout << name << " ending" << endl;
}
};
class Test3 : public Thread
{
private:
Thread& _t;
void run()
{
cout << getName() << " is joinning " << _t.getName() << endl;
_t.join();
cout << getName() << " is ending" << endl;
}
public:
Test3(Thread& t)
: _t(t) {}
};
void checkAlive(Thread& thread)
{
string name = thread.getName();
if (thread.isAlive())
{
cout << name << " is alive" << endl;
}
else
{
cout << name << " is died" << endl;
}
}
void checkInterrupt(Thread& thread)
{
string name = thread.getName();
if (thread.isInterrupted())
{
cout << name << " is interrupted" << endl;
}
else
{
cout << name << " is not interrupted" << endl;
}
}
int main()
{
try
{
Test1 t1;
Test2 t2;
t2.setName("Second Thread");
string t1Name = t1.getName();
string t2Name = t2.getName();
t1.start();
t2.start();
sleep(2);
cout << "Now joinning " << t1Name << " until 2 sec" << endl;
t1.join(2000);
checkAlive(t1);
checkAlive(t2);
try
{
cout << "Now tring restart " << t1Name << endl;
t1.start();
}
catch (exception& e)
{
cerr << typeid(e).name() << ": " << e.what() << endl;
}
sleep(2);
cout << "Now interrupt " << t1Name << endl;
cout << "Now interrupt " << t2Name << endl;
t1.interrupt();
t2.interrupt();
sleep(2);
checkAlive(t1);
checkAlive(t2);
cout << "Now joinning " << t2Name << endl;
t2.join();
Test3 t3(t1);
t3.setName("Third Thread");
t3.start();
sleep(1);
cout << "Now joinning " << t1Name << endl;
t1.join();
checkAlive(t1);
checkAlive(t2);
checkAlive(t3);
checkInterrupt(t1);
checkInterrupt(t2);
checkInterrupt(t3);
sleep(1);
cout << "Now restart " << t2Name << endl;
t2.start();
}
catch (IllegalThreadStateException& e)
{
cerr << typeid(e).name() << ": " << e.what() << endl;
}
sleep(1);
cout << "Main thread ending" << endl;
return 0;
}
Thread-0 Second Thread Thread-0 Second Thread Thread-0 Now joinning Thread-0 until 2 sec Second Thread Thread-0 Second Thread Thread-0 Thread-0 is alive Second Thread is alive Now tring restart Thread-0 27IllegalThreadStateException: Thread already started Second Thread Thread-0 Second Thread Thread-0 Now interrupt Thread-0 Now interrupt Second Thread Thread-0: Thread interrupted but continue Thread-0 Thread-0 Thread-0 is alive Second Thread is died Now joinning Second Thread Third Thread is joinning Thread-0 Thread-0 Now joinning Thread-0 Thread-0 ending Third Thread is ending Thread-0 is died Second Thread is died Third Thread is died Thread-0 is not interrupted Second Thread is interrupted Third Thread is not interrupted Now restart Second Thread 27IllegalThreadStateException: Thread had been started Main thread ending |
|
|
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù. |
|