ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®



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


  • Thread.h
#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_*/ 
 

  • Thread.cpp
#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À» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.