ã»ããã©ã¯ãE.W. ãã¤ã¯ã¹ãã© (Dijkstra) ã 1960 年代ã®çµããããã«èæ¡ããããã°ã©ãã³ã°ææ³ã§ãããã¤ã¯ã¹ãã©ã®ã»ããã©ã¢ãã«ã¯ãééç·è·¯ã®éè¡ãã¢ãã«åãããã®ã§ããä¸åº¦ã«ä¸æ¬ã®åè»ããèµ°ããªãåç·ã®ééç·è·¯ãæãæµ®ãã¹ã¦ãã ããã
ãã®ééç·è·¯ãä¿è·ããã®ãã»ããã©ã§ããåè»ã¯åç·åºéã«å ¥ãã¨ããã»ããã©ã®ç¶æ ãé²è¡è¨±å¯ç¶æ ã«ãªãã®ãå¾ ããªããã°ãªãã¾ãããåè»ãåç·åºéã«å ¥ãã¨ã»ããã©ã®ç¶æ ã¯ãä»ã®åè»ãåç·åºéã«å ¥ãã®ãç¦æ¢ããç¶æ ã«å¤åãã¾ããåç·åºéããåºãåè»ã¯ãã»ããã©ã®ç¶æ ãé²è¡è¨±å¯ç¶æ ã«æ»ãã¦ä»ã®åè»ãåç·åºéã«å ¥ããã¨ãã§ããããã«ããªããã°ãªãã¾ããã
ã³ã³ãã¥ã¼ã¿å ã®ã»ããã©ã¯ãåä¸ã®æ´æ°ã§è¡¨ç¾ããã¾ããã¹ã¬ããã¯é²è¡ã許å¯ãããã®ãå¾ ã¡ããã®å¾é²è¡ãããã¨ãç¥ãããããã«ã»ããã©ã«å¯¾ã㦠P æä½ãå®è¡ãã¾ãã
ãã®æä½ãããå°ãå ·ä½çã«èª¬æãã¾ããããã¹ã¬ããã¯ãã»ããã©ã®å¤ãæ£ã«ãªãã®ãå¾ ããªããã°ãªãã¾ããããã®å¾ 1 ãå¼ããã¨ã§ã»ããã©ã®å¤ãå¤æ´ãã¾ããããã P æä½ã§ããå¦çãå®äºããã»ããã©ã¯ãV æä½ãå®è¡ãã¾ãããã®æä½ã¯ 1 ãå ãããã¨ã§ã»ããã©ã®å¤ãå¤æ´ãã¾ããããã§å¿ ãå®ããªããã°ãªããªããã¨ãããã¾ãããããã®åæä½ãååæä½ã«ããè¡ããã¨ã§ããããã¯æä½ãåæãããã¨ãæä½éä¸ã«ã»ããã©ã«å¯¾ããå¥ã®æä½ãè¡ãããå±éºæ§ãããããã§ããP æä½ã§ã¯ã1 ãå¼ãç´åã®ã»ããã©ã®å¤ãæ£ã§ãªããã°ãªãã¾ãã (çµæçã«ãå¼ããå¾ã®å¤ãè² ã«ãªããªããã¨ã¨ããã®å¤ãå¼ãåã®å¤ããã 1 ã ãå°ãããã¨ãä¿è¨¼ããã¾ã)ã
P æä½ã¨ V æä½ã®ã©ã¡ãã®æ¼ç®æä½ã§ãå¹²æ¸ãçããªãããã«ããªããã°ãªãã¾ããããã¨ãã°ãåãã»ããã©ã«å¯¾ã㦠2 ã¤ã® V æä½ãåæã«è¡ãããå ´åããã®ã»ããã©ã®æ°ããå¤ã¯æåããã 2 ã ã大ãããªã£ã¦ããªããã°ãªãã¾ããã
ãã¤ã¯ã¹ãã©ããªã©ã³ã人ã ã£ããã¨ããããP 㨠V ã®è¨å·çãªæå³ã¯ç¾å¨ã§ã¯ã»ã¨ãã©å¿ãããã¦ãã¾ããåèã¾ã§ã«ãP ã¯ãªã©ã³ãèªã®ãprolagenãã¨ããåèªã表ãã¾ãããã®èªæºã¯ãproberen te verlagenãã§ããå°ãããããã¨ããæå³ã§ããã¾ããV ã¯ãverhogenãã表ããã大ãããããã¨ããæå³ã§ãããã®ãã¨ã¯ããã¤ã¯ã¹ãã©ã®ãã¯ãã«ã«ãã¼ããEWD 74ãã§èª¬æããã¦ãã¾ãã
sema_wait(3R) 㨠sema_post(3R) ã¯ããã¤ã¯ã¹ãã©ã® P æä½ã¨ V æä½ã«ãããã対å¿ãã¦ãã¾ããã¾ããsema_trywait(3R) ã¯ãP æä½ã®æ¡ä»¶ä»ãã®å½¢å¼ã§ãããã®é¢æ°ã¯ãå¼ã³åºãã¹ã¬ãããã»ããã©ã®å¤ãå·®ãå¼ãããã«å¾ ããªããã°ãªããªãå ´åã¯ããã ã¡ã« 0 以å¤ã®å¤ãè¿ãã¾ãã
ã»ããã©ã¯ã2 é²ã»ããã©ã¨ã«ã¦ã³ãç¨ã»ããã©ã® 2 種é¡ã«å¤§å¥ããã¾ãã2 é²ã»ããã©ã¯ 0 㨠1 ã®ã©ã¡ããã®å¤ããã¨ãã¾ãããä¸æ¹ãã«ã¦ã³ãç¨ã»ããã©ã¯è² 以å¤ã®ä»»æã®å¤ãã¨ããã¨ãã§ãã¾ãã2 é²ã»ããã©ã¯ãè«ççã«ã¯ç¸äºæä»ãã㯠(mutex ããã¯) ã¨ä¼¼ã¦ãã¾ãã
å¿ é è¦ä»¶ã§ã¯ããã¾ããããmutex ã¯ããã¯ãä¿æãã¦ããã¹ã¬ããã ãããã®ããã¯ã解æ¾ãã¹ããã®ã§ããä¸æ¹ãã»ããã©ã«ã¯ãã¹ã¬ãããã»ããã©ãä¿æãã¦ãããã¨ããæ¦å¿µããªãã®ã§ãã©ã®ã¹ã¬ããã V æä½ (ããªãã¡ãsem_post(3R)) ãå®è¡ã§ãã¾ãã
ã«ã¦ã³ãç¨ã»ããã©ã¯ãmutex ã¨ã¨ãã«ä½¿ç¨ãããæ¡ä»¶å¤æ°ã¨åçã®è½åãããã¾ããå¤ãã®å ´åãæ¡ä»¶å¤æ°ãããã«ã¦ã³ãç¨ã»ããã©ã使ç¨ããæ¹ãã³ã¼ããç°¡ç´ åããã¾ã (詳細ã¯ãå¾è¿°ã®ä¾ãåç §ãã¦ãã ãã)ã
mutex ã¨ã¨ãã«æ¡ä»¶å¤æ°ã使ç¨ããå ´åã¯ãããã°ã©ã ã®ã©ã®é¨åãä¿è·ããããèªç¶ãªå½¢ã§æããã«ãªãã¾ãããã¨ããããã»ããã©ã§ã¯å¿ ãããããã¯ãªãã¾ãããå¼·åã ããã¨ãã£ã¦å®æã«ä½¿ãã¨ããã°ã©ã ãä¸çµ±ä¸ã§ç解ãã«ãããªãã¾ãããã®ãããã並è¡ããã°ã©ãã³ã°ã«ããã go toãã¨å¼ã°ãã¦ãã¾ãã
ã»ããã©ã¯ãè² ã®å¤ãã¨ããªãæ´æ°ã®ã«ã¦ã³ã¿ã¨èãããã¨ãã§ãã¾ããé常ã¯ããªã½ã¼ã¹ã«å¯¾ããã¢ã¯ã»ã¹ã®èª¿æ´ãã¯ããç®çã§ã次ã®ããã«ä½¿ç¨ããã¾ããæåã«ã使ç¨å¯è½ãªãªã½ã¼ã¹ã®æ°ãã»ããã©ã«åæè¨å®ãã¾ãããã®å¾ãã¹ã¬ããã¯ãªã½ã¼ã¹ã追å ãããã¨ãã«ã»ããã©ã®å¤ãååçæä½ã«ãã£ã¦ 1 å¢ããããªã½ã¼ã¹ãåé¤ãããã¨ãã«ååçæä½ã«ãã£ã¦ 1 æ¸ããã¾ãã
ã»ããã©ã®å¤ã 0 ã«ãªã£ãå ´åã¯ããªã½ã¼ã¹ããªããã¨ãæå³ãã¾ãããã®å ´åãã»ããã©ã®å¤ã 1 æ¸ãããã¨ããã¨ãã¹ã¬ããã¯ã»ããã©ã®å¤ã 0 ãã大ãããªãã¾ã§ãããã¯ããã¾ãã
表 4-7 ã»ããã©ã«é¢ããã«ã¼ãã³
æä½ |
åç §å |
|
---|---|---|
ã»ããã©ã®åæå | ||
ã»ããã©ã®å ç® | ||
ã»ããã©ã®å¤ã«ããããã㯠| ||
ã»ããã©ã®æ¸ç® | ||
ã»ããã©ã®åé¤ |
ã»ããã©ã¯ããã®ç²å¾ã¨è§£æ¾ãåãã¹ã¬ããã§è¡ãå¿ è¦ããªããããã·ã°ãã«ãã³ãã©ã§è¡ããã¦ãããããªéåæã®ã¤ãã³ãéç¥ãå®ç¾ã§ãã¾ããã¾ããã»ããã©èªèº«ãç¶æ ãæã£ã¦ãããããæ¡ä»¶å¤æ°ã使ç¨ããå ´åã¨éã£ã¦ç¸äºæä»ããã¯ãç²å¾ããªãã¦ãéåæã§ä½¿ç¨ã§ãã¾ãããã ããã»ããã©ã¯ç¸äºæä»ããã¯ã»ã©å¹ççã§ã¯ããã¾ããã
ã»ããã©ã§è¤æ°ã®ã¹ã¬ããããããã¯ããã¦ããã¨ãããããã®ã¹ã¬ãããã©ã®é çªã§ãããã¯è§£é¤ããããã¯ãç¹ã«æå®ããªããã°ä¸å®ã§ãã
ã»ããã©ã¯ã使ç¨ããåã«åæåããã¦ããå¿ è¦ãããã¾ãããå±æ§ã¯ããã¾ããã
ãããã¿ã¤ã: int sem_init(sem_t *sem, int pshared, unsigned int value); #include <semaphore.h> sem_t sem; int pshared; int ret; int value; /* ã»ããã©ã®åæå */ pshared = 0; value = 1; ret = sem_init(&sem, pshared, value); |
sem_init(3R) ã¯ãsem ãæãã»ããã©å¤æ°ã value ã®å¤ã«åæè¨å®ãã¾ããpshared ã®å¤ã 0 ãªãããã®ã»ããã©ã¯ããã»ã¹éã§å ±æã§ãã¾ãããpshared ã®å¤ã 0 以å¤ãªãããã®ã»ããã©ã¯ããã»ã¹éã§å ±æã§ãã¾ãã(Solaris ã¹ã¬ããã«ã¤ãã¦ã¯ããsema_init(3T)ããåç §)ã
è¤æ°ã®ã¹ã¬ããããåãã»ããã©ãåæåãã¦ã¯ããã¾ããã
ã¾ããä¸åº¦åæåããã»ããã©ã¯ãä»ã®ã¹ã¬ããã§ä½¿ç¨ããã¦ããå¯è½æ§ãããã®ã§ååæåãã¦ã¯ããã¾ããã
æ£å¸¸çµäºæ㯠0 ã§ãããã以å¤ã®æ»ãå¤ã¯ãã¨ã©ã¼ãçºçãããã¨ã示ãã¾ãã以ä¸ã®æ¡ä»¶ã®ãããããæ¤åºãããã¨ããã®é¢æ°ã¯å¤±æãã次ã®å¤ãæ»ãã¾ãã
value ã®å¤ã SEM_VALUE_MAX ãè¶ ãã¦ãã¾ãã
ãã®ã»ããã©ãåæåããã®ã«å¿ è¦ãªãªã½ã¼ã¹ã使ãæãããã¦ãã¾ããã»ããã©ã®å¶é SEM_NSEMS_MAX ã«éãã¦ãã¾ãã
ãã®ã»ããã©ãåæåããã®ã«å¿ è¦ãªç¹æ¨©ããã®ããã»ã¹ããã£ã¦ãã¾ããã
pshared ã®å¤ã 0 ã®å ´åã¯ããã®ããã»ã¹å ã®ã¹ã¬ããã ãããã®ã»ããã©ã使ç¨ã§ãã¾ãã
#include <semaphore.h> sem_t sem; int ret; int count = 4; /* ãã®ããã»ã¹ã§ã®ã¿ä½¿ç¨ */ ret = sem_init(&sem, 0, count); |
pshared ã®å¤ã 0 以å¤ã®å ´åã¯ãä»ã®ããã»ã¹ã«ãã£ã¦ãã®ã»ããã©ã¯å ±æããã¾ãã
#include <semaphore.h> sem_t sem; int ret; int count = 4; /* ããã»ã¹éã§å ±æ */ ret = sem_init(&sem, 1, count); |
sem_open(3R)ãsem_getvalue(3R)ãsem_close(3R)ãsem_unlink(3R) ã®åé¢æ°ããååä»ãã»ããã©ãéããåå¾ãããéãããåé¤ããã®ã«ãããã使ç¨ã§ãã¾ããsem_open() ã§ã¯ããã¡ã¤ã«ã·ã¹ãã ã®åå空éã§ååãå®ç¾©ãããã»ããã©ãçæã§ãã¾ãã
ååä»ãã»ããã©ã¯ããã»ã¹éã§å ±æãããã»ããã©ã«ä¼¼ã¦ãã¾ãããpshared å¤ã§ã¯ãªããã¹åã§åç §ãããç¹ãç°ãªãã¾ãã
ååä»ãã»ããã©ã®è©³ç´°ã¯ãsem_open(3R)ãsem_getvalue(3R)ãsem_close(3R)ãsem_unlink(3R) ã®ããã¥ã¢ã«ãã¼ã¸ãåç §ãã¦ãã ããã
ãããã¿ã¤ã: int sem_post(sem_t *sem); #include <semaphore.h> sem_t sem; int ret; ret = sem_post(&sem); /* ã»ããã©ãå ç®ãã */ |
sem_post(3R) ã¯ãsem ãæãã»ããã©ã®å¤ãååæä½ã«ãã£ã¦ 1 å¢ããã¾ãããã®ã»ããã©ã§ãããã¯ããã¦ããã¹ã¬ãããããå ´åã¯ããã®ã¹ã¬ããã®ãã¡ã® 1 ã¤ã®ã¹ã¬ããããããã¯è§£é¤ããã¾ãã(Solaris ã¹ã¬ããã«ã¤ãã¦ã¯ããsema_post(3T)ããåç §)ã
æ£å¸¸çµäºæ㯠0 ã§ãããã以å¤ã®æ»ãå¤ã¯ãã¨ã©ã¼ãçºçãããã¨ã示ãã¾ãã以ä¸ã®æ¡ä»¶ãæ¤åºãããã¨ããã®é¢æ°ã¯å¤±æãã次ã®å¤ãæ»ãã¾ãã
ãããã¿ã¤ã: int sem_wait(sem_t *sem); #include <semaphore.h> sem_t sem; int ret; ret = sem_wait(&sem); /* ã»ããã©ã®å¤ã®å¤åãå¾ ã¤ */ |
sem_wait(3R) ã¯ãsem ãæãã»ããã©ã®å¤ã 0 ãã大ãããªãã¾ã§ã¹ã¬ããããããã¯ãã0 ãã大ãããªã£ããã»ããã©ã®å¤ãååæä½ã«ãã£ã¦ 1 æ¸ããã¾ãã
æ£å¸¸çµäºæ㯠0 ã§ãããã以å¤ã®æ»ãå¤ã¯ãã¨ã©ã¼ãçºçãããã¨ã示ãã¾ãã以ä¸ã®ããããã®æ¡ä»¶ãæ¤åºãããã¨ããã®é¢æ°ã¯å¤±æãã次ã®å¤ãè¿ãã¾ãã
sem ãç¡å¹ãªã¢ãã¬ã¹ãæãã¦ãã¾ãã
ãã®é¢æ°ã«ã·ã°ãã«ãå²ãè¾¼ã¿ãè¡ãã¾ããã
ãããã¿ã¤ã: int sem_trywait(sem_t *sem); #include <semaphore.h> sem_t sem; int ret; ret = sem_trywait(&sem); /* ã»ããã©ã®å¤ã®å¤åãå¾ ã¤ */ |
sem_trywait(3R) ã¯ãsem ãæãã»ããã©ã®å¤ã 0 ãã大ããå ´åã¯ååæä½ã«ãã£ã¦ 1 æ¸ããã¾ãããã®é¢æ°ã¯ãããã¯ããªãç¹ãé¤ãã¦ãsem_wait() ã¨åãåãããã¾ããã¤ã¾ãã失æããå ´åã«ã¯ããã«æ»ãã¾ãã
æ£å¸¸çµäºæ㯠0 ã§ãããã以å¤ã®æ»ãå¤ã¯ãã¨ã©ã¼ãçºçãããã¨ã示ãã¾ãã以ä¸ã®ããããã®æ¡ä»¶ãæ¤åºãããã¨ããã®é¢æ°ã¯å¤±æãã次ã®å¤ãè¿ãã¾ãã
sem ãç¡å¹ãªã¢ãã¬ã¹ãæãã¦ãã¾ãã
ãã®é¢æ°ã«ã·ã°ãã«ãå²ãè¾¼ã¿ãè¡ãã¾ããã
ãã®ã»ããã©ã¯ãã§ã«ããã¯ããã¦ããã®ã§ãsem_trywait() ã§ãã ã¡ã«ããã¯ã§ãã¾ããã
ãããã¿ã¤ã: int sem_destroy(sem_t *sem); #include <semaphore.h> sem_t sem; int ret; ret = sem_destroy(&sem); /* ã»ããã©ãåé¤ãã */ |
sem_destroy(3R) ã¯ãsem ãæãã»ããã©ãåé¤ãã¾ããã»ããã©ã®è¨æ¶é åã¯è§£æ¾ããã¾ããã(Solaris ã¹ã¬ããã«ã¤ãã¦ã¯ããsema_destroy(3T)ããåç §)ã
æ£å¸¸çµäºæ㯠0 ã§ãããã以å¤ã®æ»ãå¤ã¯ãã¨ã©ã¼ãçºçãããã¨ã示ãã¾ãã以ä¸ã®æ¡ä»¶ãæ¤åºãããã¨ããã®é¢æ°ã¯å¤±æãã次ã®å¤ãè¿ãã¾ãã
ä¾ 4-14 ã®ãã¼ã¿æ§é ã¯ãæ¡ä»¶å¤æ°ã«ãããçç£è / æ¶è²»è ãåé¡ã®ã³ã¼ãä¾ (ä¾ 4-11 åç §) ã®ãã¼ã¿æ§é ã¨ä¼¼ã¦ãã¾ãã2 ã¤ã®ã»ããã©ã§ããããããããã¡ã®ä½¿ç¨æ¸ã¹ãããæ°ã¨æªä½¿ç¨ã¹ãããæ°ã表ãã¾ãããããã®ã»ããã©ã¯ãæªä½¿ç¨ã¹ããããã§ããã¾ã§çç£è ãå¾ ããã使ç¨æ¸ã¹ããããã§ããã¾ã§æ¶è²»è ãå¾ ããã¾ãã
typedef struct { char buf[BSIZE]; sem_t occupied; sem_t empty; int nextin; int nextout; sem_t pmut; sem_t cmut; } buffer_t; buffer_t buffer; sem_init(&buffer.occupied, 0, 0); sem_init(&buffer.empty,0, BSIZE); sem_init(&buffer.pmut, 0, 1); sem_init(&buffer.cmut, 0, 1); buffer.nextin = buffer.nextout = 0; |
ããã§ã¯ãããä¸çµã® (ãã¤ããª) ã»ããã©ã使ç¨ãã¦ãã¾ãããã㯠2 å¤åã»ããã©ã§ãç¸äºæä»ãã㯠(mutex ããã¯) ã¨åãåãããã¾ãããã® 2 ã¤ã®ã»ããã©ã¯ãè¤æ°ã®çç£è ã¨è¤æ°ã®æªä½¿ç¨ã¹ããããåå¨ããå ´åã¨ãè¤æ°ã®æ¶è²»è ã¨è¤æ°ã®ä½¿ç¨æ¸ã¿ã¹ããããåå¨ããå ´åã«ããããã¡ã¸ã®ã¢ã¯ã»ã¹ãå¶å¾¡ãã¾ããæ¬æ¥ãã®ãããªå ´åã§ã¯ mutex ã使ç¨ãã¹ãã§ãããã»ããã©ã®ä½¿ç¨ä¾ã示ãããã«ç¹ã«ä½¿ç¨ãã¦ãã¾ãã
void producer(buffer_t *b, char item) { sem_wait(&b->empty); sem_wait(&b->pmut); b->buf[b->nextin] = item; b->nextin++; b->nextin %= BSIZE; sem_post(&b->pmut); sem_post(&b->occupied); } |
char consumer(buffer_t *b) { char item; sem_wait(&b->occupied); sem_wait(&b->cmut); item = b->buf[b->nextout]; b->nextout++; b->nextout %= BSIZE; sem_post(&b->cmut); sem_post(&b->empty); return(item); } |