'Study../Programming'에 해당되는 글 17건

  1. 2009.06.30 linux 에서 실행시간 확인 하기..
  2. 2009.05.29 race condition ( thread, mutex, semaphore)
linux 에서 시간을 확인할 것이 필요해서 뭐 좀 찾아봤다.
linux 에서는 time.h 를 이용하여 시간 관련된 구조체를 선언 후 시스템에서 시간을 끌어와 사용 가능하다.
시간관련 구조체를 선언 후, gettimeofday라는 것을 호출하면 시간 구조체에 시간값을 가져오게 된다.

아래는 joinc 위키 에서 찾은 gettimeofday 관련된 예제 함수.

#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main()
{
    struct timeval mytime;

    // 현재 시간을 얻어온다.
    gettimeofday(&mytime, NULL);
    printf("%ld:%ld\n", mytime.tv_sec, mytime.tv_usec);

    // 시간을 1시간 뒤로 되돌려서 설정한다.
    mytime.tv_sec -= 3600;
    settimeofday(&mytime, NULL);
    return 0;
}
그러면 timeval 구조체에 tv_sec, tv_usec 안에 초, u초 가 들어오게 된다.
일일이 뺄 수도 있지만,
친절한 메크로씨는 이미 다 선언이 되어 있다.

위에 시간 구조체를 쓰기 위한 헤더들을 선언한다면
그 안에 되어 있으므로 아래 매크로를 쓰는것은 덤. ㅋㅋㅋ
( KLDP 에서 찾았다. )
 
# define timeradd(a, b, result)                           \
  do {                                        \
    (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;                 \
    (result)->tv_usec = (a)->tv_usec + (b)->tv_usec;                  \
    if ((result)->tv_usec >= 1000000)                         \
      {                                       \
    ++(result)->tv_sec;                           \
    (result)->tv_usec -= 1000000;                         \
      }                                       \
  } while (0)
# define timersub(a, b, result)                           \
  do {                                        \
    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                 \
    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                  \
    if ((result)->tv_usec < 0) {                          \
      --(result)->tv_sec;                             \
      (result)->tv_usec += 1000000;                       \
    }                                         \
  } while (0)    

사용만 하면 되는거다.

// 헤더선언,
// 구조체 선언

gettimeofday(&mytime1, NULL);
// 실행코드
gettimeofday(&mytime2, NULL);
timersub(&mytime2, &mytime1, &result);

이런식으로 그냥 쓰면 되는거다. ㅋㅋ

'Study.. > Programming' 카테고리의 다른 글

문제가 있을 때는...  (0) 2009.08.06
IAR 에서 printf 사용하기.  (0) 2009.06.30
race condition ( thread, mutex, semaphore)  (0) 2009.05.29
no newline at end of file  (0) 2009.05.29
Javascript 계산기  (0) 2008.10.28
Posted by Yoons...
,
(글을 들어가기 전. ) 
모르고 그냥 배껴가는 타인의 소스는 자신에게 독이 된다. 
나중에 자신이 알 수 있는 기회를 빼앗어 가면 그것은 칼이 되어 자신에게 돌아간다. 
가져가는거는 좋은데, 꼭 알고 가져가길 바란다. 



race condition (서로 달리는 상태? 경쟁 상태...!!) 에 대해서 한번 보자.
다음 코드를 한번 보면 뭐 좀 이상하다 여기는게 정상이다.
(코드를 그냥 읽으면 안된다. ㅋㅋ )

#include <pthread.h>
#include <stdio.h>
#define total 10000000
void *count(void *arg);
unsigned int counter=0;
int main()
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, count, NULL);
pthread_create(&tid2, NULL, count, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
if(counter != 2*total)
printf("Oh no !\n");
else
printf("Correct \n");
}
void *count(void *arg)
{
int i;
for(i=0;i<total;i++){
counter++;
}
}
나름 조금 에러 없도록 수정한 코드. 

컴파일을 해보도록 하자. 
참고로 thread 들어간 프로그래밍은 gcc 로 컴파일 시에 옵션이 필요하다. 
-l pthread 가 들어가야 한다. 

counter++ 를 수행하면서 tid1, tid2 의 스레드가 동시에 작업을 해버리니
100% 확률로 Correct 가 나올리가 없는 코드다. 
(간간히 운 좋으면 Correct 뜨긴 뜨더라..;; ) 

counter++ 를 할때는 동시에 하나의 프로세스만 접근을 해서 실행을 해야 하는데, 
이럴때 mutex, semaphore 등을 이용하여 동시작업을 막으면 된다. 


아래는 뮤텍스를 이용하여 상호배제를 한 경우. 
 
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#define total 10000000

void *count(void *arg);

unsigned int counter=0;
pthread_mutex_t mutx; // 뮤텍스를 사용하기 위한 인자. 

int main()
{
pthread_t tid1, tid2;
pthread_mutex_init(&mutx, NULL); // 뮤텍스 초기화

pthread_create(&tid1, NULL, count, NULL);
pthread_create(&tid2, NULL, count, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
if(counter != 2*total)
printf("Oh no !\n");
else
printf("Correct \n");

pthread_mutex_destroy(&mutx); // 뮤텍스 소멸
}
void *count(void *arg)
{
int i;
for(i=0;i<total;i++){
pthread_mutex_lock(&mutx); // 뮤텍스 진입
counter++;
pthread_mutex_unlock(&mutx); // 뮤텍스 해제
}
}

main 에서는 mutex 를 init, destory 해주고, 
필요한 곳에서 lock, unlock 을 하면 된다. 

아래는 다음의 코드를 세마포어로 바꾼 코드. 

mutex 와 1:1 코드가 대응하지만, 세마포어는 다른 녀석이 풀어버릴 수도 있고, 
(반면 뮤텍스는 결자 해지다..;; ) 
init 시의 두번째 인자를 이용해서 thread 간, processor 간. 사용을 결정 할 수도 있다. 
init 시의 세번재 인자를 이용하면 동시 작업가능한 수도 바꿀 수 있다. 
  
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#define total 10000000

void *count(void *arg);

unsigned int counter=0;
sem_t sem; // 세마포어 사용하기 위한 인자

int main()
{
pthread_t tid1, tid2;
sem_init(&sem, 0, 1);  // 세마포어 초기화
// key : sem,  inter thread, # of semaphore : 1

pthread_create(&tid1, NULL, count, NULL);
pthread_create(&tid2, NULL, count, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
if(counter != 2*total)
printf("Oh no !\n");
else
printf("Correct \n");

sem_destroy(&sem);  // 세마포어 종료
}
void *count(void *arg)
{
int i;
for(i=0;i<total;i++){
sem_wait(&sem); // 세마포어 대기. 
counter++;
sem_post(&sem); // 세마포어 반환
}
}

조금 정리 해볼까? 
뮤텍스는 inter processor, binary semaphore 라고 생각하면 쉽다. 
뮤텍스는 사용이 간단하고(설정도 간단하고) 자원이나 프로세싱 속도도 세마포어 보다는 빠르다. 
반면 세마포어는 (뮤텍스에 비해서) 더 많은 오버헤드를 지니게 된다. 

뮤텍스는 하나의 열쇠를 가지고 접근할 수 있는 곳에 한번에 하나의 수행을 할 수 있도록 한다. 
세마포어는 여러개의 열쇠를 가지고 
(혹은 시작시에 열쇠가 없을 수도 있다. 동작 순서를 이용하고 처음에 post 부터 발생하게 하면 멀티 스레드의 절차적 프로그래밍을 구현 가능하다. ) 
스레드나 프로세서 사이에 공유자원에 대한 제한 / 접근이 가능하다. 

그리고 각각의 함수 형은 다음과 같은 형태를 가진다. 
(실 사용 형태나 들어가야 하는 인자는 위 코드를 보고 대충 알아서 볼것... ) 

뮤텍스
초기화 : pthread_mutex_init
소멸 : pthread_mutex_destroy
lock : pthread_mutex_lock
unlock : pthread_mutex_unlock

세마포어
초기화 : sem_init
소멸 : sem_destroy
감소 : sem_wait
증가 : sem_pos

'Study.. > Programming' 카테고리의 다른 글

IAR 에서 printf 사용하기.  (0) 2009.06.30
linux 에서 실행시간 확인 하기..  (0) 2009.06.30
no newline at end of file  (0) 2009.05.29
Javascript 계산기  (0) 2008.10.28
printf 의 16진수 / 8진수 출력..  (0) 2008.09.18
Posted by Yoons...
,