2013-02-15 9 views
17

멀티 스레드/프로세스 프로그래밍에 익숙하지 않습니다. 그래서 여기에 내가 분명히해야 할 것이있다.뮤텍스 잠금 스레드

프로세스 코드입니다 상기 의사 코드

pthread_mutex_lock() 
    pthread_create(fooAPI(sharedResource)) //fooAPI creates another thread with shared resource that shares across processes. 
pthread_mutex_unlock() 

, 프로세스 B는 뮤텍스 잠금이 해제되지 않은 경우 sharedResource 액세스 할 수 있습니까?

프로세스 B에서 sharedResource에 올바르게 액세스하려면 어떻게해야합니까?

뮤텍스, 스레드 및 프로세스 간의 관계를 설명하는 명확한 시각적 다이어그램이 있습니까? 당신이해야 할 일은

답변

30

이 같은 뮤텍스를 확보하기에 pthread_mutex_lock를 호출하는 것입니다 :이 작업을 수행 한 후에는이 스레드에서 pthread_mutex_unlock를 호출 할 때까지, pthread_mutex_lock(mutex)에 대한 다른 호출이 반환하지 않습니다

pthread_mutex_lock(&mutex); 

. 따라서 pthread_create를 호출하려고하면 새 스레드를 만들 수 있고 해당 스레드는 (잘못) 공유 리소스를 사용할 수 있습니다. fooAPI 함수에서 pthread_mutex_lock으로 전화하면 공유 자원을 사용할 수있을 때까지 함수가 대기하게됩니다.

#include <pthread.h> 
#include <stdio.h> 

int sharedResource = 0; 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

void* fooAPI(void* param) 
{ 
    pthread_mutex_lock(&mutex); 
    printf("Changing the shared resource now.\n"); 
    sharedResource = 42; 
    pthread_mutex_unlock(&mutex); 
    return 0; 
} 

int main() 
{ 
    pthread_t thread; 

    // Really not locking for any reason other than to make the point. 
    pthread_mutex_lock(&mutex); 
    pthread_create(&thread, NULL, fooAPI, NULL); 
    sleep(1); 
    pthread_mutex_unlock(&mutex); 

    // Now we need to lock to use the shared resource. 
    pthread_mutex_lock(&mutex); 
    printf("%d\n", sharedResource); 
    pthread_mutex_unlock(&mutex); 
} 

편집 :

그래서 당신은이 같은 것이 동일한 기본 접근 방법을 다음과 프로세스를 통해 자원을 사용하여,하지만 당신은 다른 프로세스에 메모리를 매핑해야합니다. 여기에 예제 사용 shmem과의 :

#include <stdio.h> 
#include <unistd.h> 
#include <sys/file.h> 
#include <sys/mman.h> 
#include <sys/wait.h> 

struct shared { 
    pthread_mutex_t mutex; 
    int sharedResource; 
}; 

int main() 
{ 
    int fd = shm_open("/foo", O_CREAT | O_TRUNC | O_RDWR, 0600); 
    ftruncate(fd, sizeof(struct shared)); 

    struct shared *p = (struct shared*)mmap(0, sizeof(struct shared), 
     PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 

    p->sharedResource = 0; 

    // Make sure it can be shared across processes 
    pthread_mutexattr_t shared; 
    pthread_mutexattr_init(&shared); 
    pthread_mutexattr_setpshared(&shared, PTHREAD_PROCESS_SHARED); 

    pthread_mutex_init(&(p->mutex), &shared); 

    int i; 
    for (i = 0; i < 100; i++) { 
     pthread_mutex_lock(&(p->mutex)); 
     printf("%d\n", p->sharedResource); 
     pthread_mutex_unlock(&(p->mutex)); 
     sleep(1); 
    } 

    munmap(p, sizeof(struct shared*)); 
    shm_unlink("/foo"); 
} 

P-을 변경할 수있는 프로그램을 작성> sharedResource는 독자들에게 운동으로 남아 있습니다. :-)

뮤텍스가 PTHREAD_PROCESS_SHARED 속성을 가져야한다는 것을 잊어 버리십시오. 그러면 pthread가 프로세스에서 작동합니다.

+0

이 매우 분명하다. 또한 다른 응용 프로그램 인 프로세스 B가 sharedResource에 액세스 할 수있는 방법의 예를 포함시킬 수 있습니까? – resting

2

Q1.) 프로세스 B가 프로세스 A에서 잠긴 동일한 뮤텍스 (소유 한 의사 코드에서 제외)의 소유권을 얻으려고하면 다음 프로세스를 수행 할 수 없습니다. 프로세스 B는 sharedResource에 액세스 할 수 없습니다. 뮤텍스가 잠길 때 (또는 오류가 발생할 때) mutex_lock() 함수에서 반환됩니다.

Q2.) 프로세스 B에서 항상 뮤텍스, 공유 리소스에 액세스 한 다음 뮤텍스를 잠금 해제합니다. 또한 mutex_lock (pMutex) 루틴의 리턴 코드를 점검하여 실제로 뮤텍스를 소유하는지 확인하고, 뮤텍스를 잠근 경우에만 잠금을 해제하십시오. 프로세스 A에서 동일한 작업을 수행하십시오.

두 프로세스는 기본적으로 뮤텍스에 액세스 할 때 동일한 작업을 수행해야합니다.
잠금() 잠금 후, 성공하면 { 액세스 sharedResource 잠금 해제를() }

Q3) 예, 다이어그램의 많은이 있습니다. =) https://www.google.se/search?q=mutex+thread+process&rlz=1C1AFAB_enSE487SE487&um=1&ie=UTF-8&hl=en&tbm=isch&source=og&sa=N&tab=wi&ei=ErodUcSmKqf54QS6nYDoAw&biw=1200&bih=1730&sei=FbodUbPbB6mF4ATarIBQ

1

이 프로세스는 구성은 적어도 하나의 스레드 (주 함수를 생각해 보라). 다중 스레드 코드는 더 많은 스레드를 생성합니다. 뮤텍스는 데이터 손상/예기치 않은/원치 않는 동작을 방지하기 위해 공유 리소스를 잠그는 데 사용됩니다. 기본적으로 비동기식 설정에서 순차적 실행을 제공합니다. 공유 데이터 구조에서 non-const 비 원자 연산에서 유래 한 요구 사항입니다.

화장실 (공유 자원)을 방문하기 위해 대기중인 사람 (스레드)의 경우 어떤 mutex가 생기는지 생생하게 설명합니다. 한 사람 (쓰레드)이 화장실을 사용하고있는 동안 (비 const non-atomic operation), 문이 잠겨 있는지 (뮤텍스) 확인해야합니다. 그렇지 않으면 원하지 않는 행동으로 이어질 수 있습니다)

2

아래의 코드 스 니펫은 뮤텍스 잠금 잠금 해제 개념을 이해하는 데 도움이됩니다. 코드에서 마른 실행을 시도하십시오. (대기 시간과 처리 시간을 변경하여 이해를 도울 수 있습니다). 참조 용

코드 :

#include <stdio.h> 
#include <pthread.h> 

void in_progress_feedback(int); 

int global = 0; 
pthread_mutex_t mutex; 
void *compute(void *arg) { 

    pthread_t ptid = pthread_self(); 
    printf("ptid : %08x \n", (int)ptid);  

    int i; 
    int lock_ret = 1; 
    do{ 

     lock_ret = pthread_mutex_trylock(&mutex); 
     if(lock_ret){ 
      printf("lock failed(%08x :: %d)..attempt again after 2secs..\n", (int)ptid, lock_ret); 
      sleep(2); //wait time here.. 
     }else{ //ret =0 is successful lock 
      printf("lock success(%08x :: %d)..\n", (int)ptid, lock_ret); 
      break; 
     } 

    } while(lock_ret); 

     for (i = 0; i < 10*10 ; i++) 
     global++; 

    //do some stuff here 
    in_progress_feedback(10); //processing-time here.. 

    lock_ret = pthread_mutex_unlock(&mutex); 
    printf("unlocked(%08x :: %d)..!\n", (int)ptid, lock_ret); 

    return NULL; 
} 

void in_progress_feedback(int prog_delay){ 

    int i=0; 
    for(;i<prog_delay;i++){ 
    printf(". "); 
    sleep(1); 
    fflush(stdout); 
    } 

    printf("\n"); 
    fflush(stdout); 
} 

int main(void) 
{ 
    pthread_t tid0,tid1; 
    pthread_mutex_init(&mutex, NULL); 
    pthread_create(&tid0, NULL, compute, NULL); 
    pthread_create(&tid1, NULL, compute, NULL); 
    pthread_join(tid0, NULL); 
    pthread_join(tid1, NULL); 
    printf("global = %d\n", global); 
    pthread_mutex_destroy(&mutex); 
      return 0; 
} 
+0

void * compute() 함수는 호출 될 때만 실행되거나이 스레드를 실행하여 백그라운드에서이 함수를 지속적으로 실행하도록 할 수 있습니까? – LandonZeKepitelOfGreytBritn

+0

스레드가 생성 될 때, 생성 된 스레드와 결합 된 메소드는 스레드에서 실행을 시작합니다 (이 경우'compute()'). 스폰 된 스레드가 없으면 여전히 메인 스레드 ('main()'이 실행되는 곳)에 있습니다. 이제 스레드가 백그라운드에서 무언가를 수행하도록 만들려면, 종료되지 않은 조건 (즉, 바인딩 된 메서드가 종료되도록하지 말고, 닫을 것을 요청할 때까지)에서 바인딩 메서드에 대한 실행을 유지해야합니다. 스레드에 신호가있을 때 종료 조건, 종료해야합니다 (정리 등). 그렇지 않으면 원하는 작업을 수행하기 위해 유지됩니다. – parasrish