wait()¿Í notify()´Â µ¿ÀÏÇÑ Àá±Ý °´Ã¼ ÇÏ¿¡¼ µ¿±âÈµÇ¾î ½ÇÇàµÇ´Â ºí·Ï¿¡¼ ½ÇÇàµÉ ¼ö ÀÖ´Ù.
notify() ÀÌÈÄÀÇ ½ÇÇà ¼ø¼´Â ¸ÕÀú notify()¸¦ È£ÃâÇÑ ¾²·¹µå°¡ synchronized ºí·ÏÀ» ¹þ¾î³ ´ÙÀ½¿¡ wait()ÇÏ´Ù ±ú¾î³ ¾²·¹µåÀÇ ¼öÇàÀ» º¸ÀåÇÏ´Â ¼ø¼·Î µÈ´Ù.
|
Âü°í: Mesa ¹æ½Ä°ú Hoare ¹æ½Ä Mesa ¹æ½Ä¿¡¼´Â wait()ÇÏ´ø ¾²·¹µå°¡ ´Ù½Ã Àá±ÝÀ» ȹµæÇÏ´Â °ÍÀº ¼øÀüÈ÷ wait()ÇÏ´ø °´Ã¼ÀÇ Ã¥ÀÓÀÌ´Ù. Áï, notify()ÇÏ´ø ¾²·¹µå´Â wait()ÇÏ´Â °´Ã¼¸¦ Àá±ÝÀ» ȹµæÇÏ·Á°í ÇÏ´Â(½ºÄÉÁìµÇ·Á°í ÇÏ´Â) ¾²·¹µå ¸ñ·Ï¿¡ ¿Ã·ÁÁÙ »Ó, ÀÚ½ÅÀÇ ÀӰ迵¿ª(critical section)À» °è¼Ó ¼öÇàÇÑ ´ÙÀ½ ÀÓ°è ¿µ¿ªÀ» ¹þ¾î³ª¸é¼ Àá±ÝÀ» Ǭ´Ù. Hoare ¹æ½Ä¿¡¼´Â notify()ÇÏ´ø ¾²·¹µå°¡ Àá½Ã Àá±ÝÀ» Ç®°í Á¦¾î¸¦ ±ú¾î³¯ ¾²·¹µå¿¡°Ô ³Ñ°ÜÁØ´Ù. wait()ÇÏ´ø °´Ã¼°¡ ÀӰ迵¿ª ¼öÇàÀ» ¸¶Ä£ ÈÄ ´Ù½Ã notify()Çß´ø ¾²·¹µå¿¡°Ô Àá±Ý¿¡ ´ëÇÑ Á¦¾î¸¦ µ¹·ÁÁØ´Ù. Mesa ¹æ½ÄÀ» »ç¿ëÇÏ°Ô µÇ¸é ±ú¾î³ ¾²·¹µå°¡ ½ÇÇàµÇ±â Àü¿¡ ¾î¶² ´Ù¸¥ ¾²·¹µå°¡ Àá±ÝÀ» ȹµæÇÏ¿© ¼öÇàµÇ¸é¼ µ¥ÀÌÅ͸¦ º¯°æ½Ãų ¼ö ÀÖ´Â ´ÜÁ¡ÀÌ ÀÖ´Ù. ±×·¯³ª Hoare ¹æ½Ä¿¡ ºñÇØ ±¸ÇöÀÌ ÈξÀ ½±´Ù´Â ÀåÁ¡ÀÌ ÀÖ´Ù.
ÀÚ¹ÙÀÇ ±¸ÇöÀº Mesa ¹æ½ÄÀÌ´Ù. °¢ Àá±Ý °´Ã¼¿¡´Â ±â´Ù¸®´Â ¾²·¹µå ¸ñ·Ï(wait set)ÀÌ ÀÖ¾î¼ notify()¸¦ Çϸé wait set¿¡ ÀÖ´Â ¾²·¹µåµé Áß ÀÓÀÇÀÇ Çϳª¸¦ wait set¿¡¼ Áö¿ö¼ ´Ù½Ã ½ºÄÉÁ층µÉ ¼ö ÀÖµµ·Ï ÇÑ´Ù. ¹°·Ð notify()ÇÑ ¾²·¹µå°¡ ÀӰ迵¿ªÀ» ¹þ¾î³ª Àá±ÝÀ» Ç®Áö ¾Ê´Â ÇÑ ½ºÄÉÁ층µÈ ¾²·¹µå°¡ Àá±ÝÀ» ȹµæÇÒ ¼ö´Â ¾ø´Ù.
|
¾²·¹µå°¡ wait()¿¡ µµ´ÞÇϸé Àá±Ý °´Ã¼¸¦ Ç®°í notify()µÇ±â¸¦ ±â´Ù¸®´Ù°¡ notify()·Î ÀÎÇØ ±ú¾î³ ´ÙÀ½¿¡ ÀÚµ¿À¸·Î ´Ù½Ã Àá±Ý °´Ã¼¸¦ Àá±×°í ³ª¸ÓÁö synchronized ºí·Ï ³»ºÎ¸¦ ¼öÇàÇÏ°Ô µÈ´Ù.
À¯´Ð½º POSIX ¾²·¹µå ÇÁ·Î±×·¡¹ÖÀ» ÇÒ ¶§ÀÇ pthread_cond_signal()°ú pthread_cond_wait() ÇÔ¼ö°¡ °¢°¢ ÀÚ¹ÙÀÇ notify(), wait()¿¡ ÇØ´çÇÑ´Ù°í º¼ ¼ö ÀÖ´Ù.
/*
* WaitTest.java
* Copyright 1998 yoonforh@yahoo.com
*/
class WaitTest {
int value;
class Putter extends Thread {
Object locker;
public Putter(Object locker) {
this.locker=locker;
}
public void run() {
doPut(locker);
}
}
void doPut(Object obj) {
synchronized (obj) {
value++;
System.out.println("PUTTER["+Thread.currentThread().getName()+"]:value="+value);
notify();
System.out.println("PUTTER["+Thread.currentThread().getName()+"]:after notify");
}
}
class Getter extends Thread {
Object locker;
public Getter(Object locker) {
this.locker=locker;
}
public void run() {
doGet(locker);
}
}
void doGet(Object obj) {
synchronized (obj) {
System.out.println("GETTER["+Thread.currentThread().getName()+"]:before wait");
try {
wait();
} catch (InterruptedException ie) {
System.out.println("Interrupted...");
}
value--;
System.out.println("GETTER["+Thread.currentThread().getName()+"]:value="+value);
}
}
public WaitTest() {
Thread one = new Putter(this);
Thread two = new Putter(this);
Thread three = new Putter(this);
Thread four = new Putter(this);
Thread five = new Putter(this);
Thread six = new Getter(this);
Thread seven = new Getter(this);
Thread eight = new Getter(this);
Thread nine = new Getter(this);
Thread ten = new Getter(this);
six.start();
seven.start();
eight.start();
nine.start();
ten.start();
one.start();
two.start();
three.start();
four.start();
five.start();
}
public static void main(String args[]) {
new WaitTest();
}
}
½ÇÇà °á°ú ¿¹ 1(Digital Unix 4.0B(1CPU) JDK 1.1.6¿¡¼ ½ÇÇà)
GETTER[Thread-7]:before wait GETTER[Thread-8]:before wait GETTER[Thread-9]:before wait GETTER[Thread-10]:before wait GETTER[Thread-11]:before wait PUTTER[Thread-2]:value=1 PUTTER[Thread-2]:after notify GETTER[Thread-7]:value=0 PUTTER[Thread-3]:value=1 PUTTER[Thread-3]:after notify PUTTER[Thread-4]:value=2 PUTTER[Thread-4]:after notify GETTER[Thread-8]:value=1 PUTTER[Thread-5]:value=2 PUTTER[Thread-5]:after notify GETTER[Thread-9]:value=1 PUTTER[Thread-6]:value=2 PUTTER[Thread-6]:after notify GETTER[Thread-10]:value=1 GETTER[Thread-11]:value=0½ÇÇà °á°ú ¿¹ 2(Digital Unix 4.0B(1CPU) JDK 1.1.6¿¡¼ ½ÇÇà)
GETTER[Thread-7]:before wait PUTTER[Thread-2]:value=1 PUTTER[Thread-2]:after notify PUTTER[Thread-3]:value=2 PUTTER[Thread-3]:after notify <- waitÇϰí ÀÖ´Â ¾²·¹µå°¡ ¾ø´Âµ¥ notify PUTTER[Thread-4]:value=3 PUTTER[Thread-4]:after notify <- waitÇϰí ÀÖ´Â ¾²·¹µå°¡ ¾ø´Âµ¥ notify GETTER[Thread-7]:value=2 GETTER[Thread-8]:before wait PUTTER[Thread-5]:value=3 PUTTER[Thread-5]:after notify GETTER[Thread-9]:before wait PUTTER[Thread-6]:value=4 PUTTER[Thread-6]:after notify GETTER[Thread-10]:before wait <- ÀÌ ¾²·¹µå´Â ¹«ÇÑÈ÷ ±â´Ù¸®°Ô µÈ´Ù. GETTER[Thread-8]:value=3 GETTER[Thread-11]:before wait <- ÀÌ ¾²·¹µå´Â ¹«ÇÑÈ÷ ±â´Ù¸®°Ô µÈ´Ù. GETTER[Thread-9]:value=2
/*
* condtest.c
* Copyright 1998 yoonforh@yahoo.com
*/
#include <pthread.h>
#include <stdio.h>
/******************************** DEFINES *****************************/
#define NUMTHREADS 10
#define NUM_PUTTERS 5
#define NUM_GETTERS 5
pthread_mutex_t mutex;
pthread_cond_t cond;
int value=0;
main(int argc, char **argv)
{
int numThr;
pthread_t threadId[NUMTHREADS];
pthread_attr_t threadAttr;
void *Getters();
void *Putters();
int i;
int *status;
pthread_mutexattr_t *m_attr;
pthread_condattr_t *c_attr;
m_attr=(pthread_mutexattr_t *) malloc(sizeof(pthread_mutexattr_t));
c_attr=(pthread_condattr_t *) malloc(sizeof(pthread_condattr_t));
pthread_mutexattr_init(m_attr);
pthread_condattr_init(c_attr);
pthread_mutex_init(&mutex , m_attr);
pthread_cond_init(&cond , c_attr);
numThr = NUM_PUTTERS + NUM_GETTERS;
if (numThr > NUMTHREADS)
exit(0);
pthread_attr_init(&threadAttr);
for (i = 0; i < NUM_PUTTERS; ++i)
pthread_create(&threadId[i], &threadAttr, Getters, NULL);
for (i= NUM_PUTTERS ; i < numThr; ++i)
pthread_create(&threadId[i], &threadAttr, Putters, NULL);
for (i = 0; i < numThr; ++i)
pthread_join(threadId[i],(void**) &status);
exit(0);
}
void *
Putters(void *pThrArg)
{
pthread_t Tid;
int i;
char msg[256];
Tid = pthread_self();
pthread_mutex_lock(&mutex);
value++;
fprintf(stderr, "PUTTER[%d]:value=%d\n", Tid, value);
pthread_cond_signal(&cond);
fprintf(stderr, "PUTTER[%d]:after cond_signal\n", Tid);
pthread_mutex_unlock(&mutex);
return(NULL);
}
void *
Getters(void *pThrArg)
{
volatile int i;
int nmsgs;
int Rc;
char msg[256];
pthread_t Tid;
Tid = pthread_self();
pthread_mutex_lock(&mutex);
fprintf(stderr, "GETTER[%d]:before cond_wait\n", Tid);
pthread_cond_wait(&cond, &mutex);
value--;
fprintf(stderr, "GETTER[%d]:value=%d\n", Tid, value);
pthread_mutex_unlock(&mutex);
return(NULL);
}
½ÇÇà °á°ú ¿¹(Digital Unix 4.0B(1CPU)¿¡¼ ½ÇÇà)
GETTER[1073797136]:before cond_wait GETTER[1073840176]:before cond_wait GETTER[1073841552]:before cond_wait GETTER[1073842928]:before cond_wait GETTER[1073844304]:before cond_wait PUTTER[1073845680]:value=1 PUTTER[1073845680]:after cond_signal PUTTER[1073889328]:value=2 PUTTER[1073889328]:after cond_signal PUTTER[1073890704]:value=3 PUTTER[1073890704]:after cond_signal PUTTER[1073892080]:value=4 PUTTER[1073892080]:after cond_signal PUTTER[1073893456]:value=5 PUTTER[1073893456]:after cond_signal GETTER[1073797136]:value=4 GETTER[1073840176]:value=3 GETTER[1073841552]:value=2 GETTER[1073842928]:value=1 GETTER[1073844304]:value=0