Threads의 기본 사용 방법

POSIX Threads
1.1 Thread 기본 요소
ž루틴 조작은 창설, 종료, 동기화(joins, Blocking), 스케줄링, 데이터 관리, 과정 상호작용을 포함한다.
ž하나의 라인이 생성된 라인 목록을 유지하지 않습니다. 어떤 라인이 생성되었는지 알 수 없습니다.
ž하나의 프로세스의 모든 라인에서 같은 주소 공간을 공유합니다.
ž같은 프로세스의 스레드 공유: Process instructions, Most data,open files,signals and handlers,current working directory,user and group id.
ž스레드마다 Thread ID, set of registers, stack pointer, stack for local variables,return addresses,signal mask,priority,return value(errno)가 다릅니다.
žPthreads 함수가 0을 반환하면 성공이 표시됩니다.
1.2 Thread 생성 및 종료
Example:pthread1.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *print_message_function( void *ptr );

main()
{
     pthread_t thread1, thread2;
     const char *message1 = "Thread 1";
     const char *message2 = "Thread 2";
     int  iret1, iret2;

    /*         ,           */
     iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
     /*    1   2  */
     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL); 

     printf("Thread 1 returns: %d
",iret1); printf("Thread 2 returns: %d
",iret2); exit(0); } void *print_message_function( void *ptr ) { char *message; message = (char *) ptr; printf("%s
", message); }

 
컴파일링: gcc – o pthread 1 – lpthread pthread 1.c
실행:./pthread1
Thread 1
Thread 2
Thread 1 returns: 0
Thread 2 returns: 0

ž루틴의 종료를 표시할 수 있는 호출 pthreadexit는 리셋 함수를 되돌려 주거나 프로세스를 종료하고 포함된 모든 라인을 호출합니다.
ž함수 호출:pthreadcreate - 새 스레드 만들기
  int  pthread_create(pthread_t *thread,
                  const pthread_attr_t * attr,
                  void * (*start_routine)(void *),
                  void *arg);
매개변수:
thread: unsigned long int 형식의 루틴을 반환합니다.bits/pthreadtypes에 정의됩니다.h중.
attr: 기본 속성을 사용하면 NULL로 설정하고 그렇지 않으면 구조 pthread 를 정의해야 합니다.attr_t(bits/pthreadtypes.h)의 구성원.속성 값은 Man입니다.
void*(*start routine): 라인을 가리키는 입구 함수로 void형을 가리키는 바늘이 포함되어 있습니다.
*arg: 함수의 매개 변수, 다중 매개 변수를 전달할 때 구조체를 가리키는 지침을 사용합니다.
ž함수 호출:pthreadjoin - 다른 스레드가 종료될 때까지 기다림
  int  pthread_join(pthread_t  th,
                void **thread_return);
매개변수:
th:스레드 ID
 thread_return: 이 값이 비어 있지 않으면 되돌아오는 값은thread 에 저장됩니다return이 가리키는 주소입니다.
ž함수 호출:pthreadexit - 호출을 중지하는 스레드
 
void  pthread_exit(void *retval);
매개 변수:retval: 라인의 반환값입니다.이 변수는 국부 변수가 될 수 없다.
이 함수는kill의 라인을 사용합니다.
주석: C에 대해 아래의 방식으로 입구 함수를 입력한다.
void print_message_function( void *ptr );
...
...
iret1 = pthread_create( &thread1, NULL, (void*)&print_message_function, (void*) message1);
...
...

1.3 Thread 동기화
P_thread 라이브러리는 세 가지 루틴 동기화 메커니즘을 제공합니다:mutexes (상호 잠금),joins (한 루틴이 다른 루틴이 끝날 때까지 기다리게 함),condition variables (조건 변수, 유형은 pthread cond t)
Mutexes
주로 메모리 데이터의 일치성을 보호하고 자원 경쟁을 방지하는데 여러 라인이 같은 메모리의 데이터를 동시에 조작할 때 데이터가 일치하지 않을 수 있다.Mutexes는 단일 프로세스의 여러 스레드에서만 사용할 수 있으며 다른 프로세스에서는 사용할 수 없지만 semaphores는 다른 프로세스에서 사용할 수 있습니다.
자물쇠 없음
 int counter = 0;
void functionC()
{
counter++;
}
 
자물쇠가 있다
/* 변수 및 잠금 범위는 동일*/
/*           */
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALZER;
int counter = 0;
void function()
{
pthread_mutex_lock(&mutex1);
counter++;
pthread_mutex_unlock(&mutex1);
}

 
Example:mutex1.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;//     
int  counter = 0;

main()
{
   int rc1, rc2;
   pthread_t thread1, thread2;
   if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
   {
      printf("Thread creation failed: %d
", rc1); } if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) ) { printf("Thread creation failed: %d
", rc2); } pthread_join( thread1, NULL); pthread_join( thread2, NULL); exit(0); } void *functionC() { pthread_mutex_lock( &mutex1 ); counter++; printf("Counter value: %d
",counter); pthread_mutex_unlock( &mutex1 ); }

 
컴파일링: gcc – o mutex1 – lpthread mutex 1.c
실행 결과:
Counter value: 1 Counter value: 2
 
example :join1.c
include <stdio.h>
#include <pthread.h>

#define NTHREADS 10
void *thread_function(void *);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int  counter = 0;

main()
{
   pthread_t thread_id[NTHREADS];
   int i, j;

   for(i=0; i < NTHREADS; i++)
   {
      pthread_create( &thread_id[i], NULL, thread_function, NULL );
   }

   for(j=0; j < NTHREADS; j++)
   {
      pthread_join( thread_id[j], NULL); 
   }
  
   /*                */

   printf("Final counter value: %d
", counter); } void *thread_function(void *dummyPtr) { printf("Thread number %ld
", pthread_self()); pthread_mutex_lock( &mutex1 ); counter++; pthread_mutex_unlock( &mutex1 ); }

cc -pthread join1.c or cc -lpthread join1.c
Thread number 1026
Thread number 2051
Thread number 3076
Thread number 4101
Thread number 5126
Thread number 6151
Thread number 7176
Thread number 8201
Thread number 9226
Thread number 10251
Final counter value: 10

조건 변수 pthreadcond_t
조건 변수는 스레드의 실행을 중단시키고 조건 변수가 진짜가 될 때까지 CPU를 내보냅니다.조건 변수는 자물쇠와 함께 사용해 임계 자원 경쟁을 방지해야 한다.
Creating/Destroying:
pthread_cond_init 초기화pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_Destroy 제거
Waiting on condition:
pthread_cond_wait – 잠금 해제 및 조건 발생 대기pthread_cond_timedwait – 조건 차단 설정 시간
Waking thread based on condition:
pthread_cond_signal - 등조건 변수에서 시작하는 스레드
  • pthread_cond_broadcast - 이 조건 변수에 의해 막힌 모든 라인을 깨우기
  • Example code:cond.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    //         
    pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;
    
    void *functionCount1();
    void *functionCount2();
    int  count = 0;
    #define COUNT_DONE  10
    #define COUNT_HALT1  3
    #define COUNT_HALT2  6
    
    main()
    {
       pthread_t thread1, thread2;
       //             
       pthread_create( &thread1, NULL, &functionCount1, NULL);
       pthread_create( &thread2, NULL, &functionCount2, NULL);
       //        
       pthread_join( thread1, NULL);
       pthread_join( thread2, NULL);
    
       printf("Final count: %d
    ",count); exit(0); } // functionCount2() , 1-3 8-10 void *functionCount1() { for(;;) { // Lock mutex and then wait for signal to relase mutex pthread_mutex_lock( &count_mutex ); // count_mutex, pthread_cond_wait( &condition_var, &count_mutex ); count++; printf("Counter value functionCount1: %d
    ",count); pthread_mutex_unlock( &count_mutex ); if(count >= COUNT_DONE) return(NULL); } } // 4-7 void *functionCount2() { for(;;) { pthread_mutex_lock( &count_mutex ); if( count < COUNT_HALT1 || count > COUNT_HALT2 ) { // , , pthread_cond_signal( &condition_var ); } else { count++; printf("Counter value functionCount2: %d
    ",count); } pthread_mutex_unlock( &count_mutex ); if(count >= COUNT_DONE) return(NULL); } }
    cc -pthread cond1.c or cc -lpthread cond1.c
    Counter value functionCount1: 1
    Counter value functionCount1: 2
    Counter value functionCount1: 3
    Counter value functionCount2: 4
    Counter value functionCount2: 5
    Counter value functionCount2: 6
    Counter value functionCount2: 7
    Counter value functionCount1: 8
    Counter value functionCount1: 9
    Counter value functionCount1: 10
    Final count: 10

    스레드 트랩
    1. 조건 경쟁: 다중 스레드 환경에서 코드의 집행 순서는 쓴 순서에 따라 집행되지 않을 수 있다. 운영체제의 스케줄링으로 인해 각 스레드의 집행 순서가 다르고 각 스레드의 집행 속도도 다르기 때문에 예측할 수 없는 결과를 초래할 수 있다.
    2. 스레드 보안 코드: 정적 변수와 전역 변수에 대한 접근은 반드시 잠그고 다시 들어갈 수 없는 함수를 사용하지 마십시오.strtok 함수와 같이 안전한 함수를 사용해야 합니다 strtokr.
    3. 라인 잠금 해제: 두 개 이상의 자물쇠를 사용할 때 잠금이 해제되는 것을 방지해야 한다.아래의 방법을 사용하여 자물쇠가 사라지는 것을 방지할 수 있다.
    ...
    pthread_mutex_lock(&mutex_1);
    while ( pthread_mutex_trylock(&mutex_2) )  /* Test if already locked   */
    {
       pthread_mutex_unlock(&mutex_1);  /* Free resource to avoid deadlock */
       ...
       /* stall here   */
       ...
       pthread_mutex_lock(&mutex_1);
    }
    count++;
    pthread_mutex_unlock(&mutex_1);
    pthread_mutex_unlock(&mutex_2);
    ...
    

    좋은 웹페이지 즐겨찾기