linux 다중 루틴의posix 신호량
6276 단어 linux 환경 개발
1. 멀티태스킹 운영 체제에서 보통 자원은 고정된 수량으로 사용할 수 있다. 예를 들어 프린터라는 외부 장치.그러나 이 자원을 사용해야 하는 임무가 매우 많은데 이때 신호량으로 자원의 사용을 조율할 수 있다(물론 자원 내부에서 자물쇠를 사용해도 같은 효과를 얻을 수 있다).2. 신호량은 운영 체제에 의해 PV 조작으로 실현된다. P(passeren)는 자원을 소모하고 신호량을 감소시킨다.V(vrijgeven), 자원을 방출하고 신호량에 대한 추가 조작을 한다.PV 조작은 모두 원자 조작이다.3. 퀘스트 A가 P조작을 해야 하는데 신호량이 0일 경우 퀘스트 A는 다른 퀘스트가 V조작을 해서 사용 가능한 자원이 생길 때까지 막힌다.
posix 신호량 예시
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include /* For O_* constants */
#include /* For mode constants */
#include
#define DBG_PRINT(fmt, args...) {printf("%s %d ", __FUNCTION__, __LINE__);printf(fmt,##args);}
/**
* [msDelay_select select() ms ]
* @param msTime [ msTime , ]
*/
void msDelay_select(unsigned msTime)
{
struct timeval time;
if(msTime == 0)
{
DBG_PRINT("delay time can not be 0!
");
return;
}
if(msTime>=1000)
{
time.tv_sec = msTime/1000;
time.tv_usec = (unsigned long)(msTime%1000)*1000UL;
}
else
{
time.tv_sec = 0;
time.tv_usec = (unsigned long)msTime*1000UL;
}
select(0, NULL, NULL, NULL, &time);
}
static sem_t semID;
static char testStr[1024];
void* testThead(void* arg)
{
int ret = 0;
prctl(PR_SET_NAME, "Sem Test Task");
while(1)
{
/**
* sem_wait 0, ;
* sem_wait , , ;
* sem_trywait ;sem_timedwait ;
*/
ret = sem_wait(&semID);
if(ret != 0)
{
DBG_PRINT("sem_post failed, errno:%s
", strerror(errno));
msDelay_select(300);
continue;
}
/**
* fgets stdin testStr , ;
* , fgets() , ;
*/
DBG_PRINT("The testStr is:%s", testStr);
msDelay_select(100);
}
}
int main(int argc, const char* argv[])
{
int ret = 0;
pthread_t threadID;
/**
* , 0 ;
* 1 1, 1 ;
*/
ret = sem_init(&semID, 0, 0);
if(ret != 0)
{
DBG_PRINT("sem_init failed, errno:%s
", strerror(errno));
return -1;
}
/**
* testThead
*/
ret = pthread_create(&threadID, NULL, testThead, NULL);
if(ret != 0)
{
DBG_PRINT("pthread_create failed, errno:%s
", strerror(ret));
return -1;
}
while(1)
{
/**
* ; "exit"
*/
fgets(testStr, 1023, stdin);
if(0 == strncmp(testStr, "exit", 4))
{
DBG_PRINT("exit the semaphore test!
")
ret = sem_destroy(&semID);
if(ret != 0)
{
DBG_PRINT("DBG_PRINT failed, errno:%s
", strerror(errno));
}
break;
}
/**
* 1 ;
*/
ret = sem_post(&semID);
if(ret != 0)
{
DBG_PRINT("sem_post failed, errno:%s
", strerror(errno));
return -1;
}
}
return 0;
}