2012-06-24 3 views
0

으로 다른 값을 제공합니다 나는 다음과 같은 코드가 있습니다공유 카운터 스핀 락

7: Incrementing counter: 996 -> 997 
7: Incrementing counter: 997 -> 998 
7: Incrementing counter: 998 -> 999 
7: Incrementing counter: 999 -> 1000 
Sum: 1000 
Main: Program completed. Exiting. 

내가 한 경우 : PRINT 1로 정의하면

#include <stdio.h> 
#include <pthread.h> 
#define THREAD_CNT 10 
#define ITER 100 
#define PRINT 1 

int lock; 
unsigned long long int counter; 

void spin_lock(int *p) { 
    while(!__sync_bool_compare_and_swap(p, 0, 1)); 
} 

void spin_unlock(int volatile *p) { 
    asm volatile (""); 
    *p = 0; 
} 

void *exerciser(void *arg) { 
    unsigned long long int i; 
    int id = (int)arg; 
    for(i = 0; i < ITER; i++) { 
     spin_lock(&lock); 
     counter = counter + 1; 
     if(PRINT) { 
      printf("%d: Incrementing counter: %llu -> %llu\n", id, counter-1, counter); 
     } 
     spin_unlock(&lock); 
    } 
    pthread_exit(NULL); 
} 

int main(int argc, char *argv[]) { 
    pthread_t thread[THREAD_CNT]; 
    counter = 0; 
    int i; 
    for(i = 0; i < THREAD_CNT; i++) { 
     pthread_create(&thread[i], NULL, exerciser, (void *) i); 
    } 
    for(i = 0; i < THREAD_CNT; i++) { 
     pthread_join(thread[i], NULL); 
    } 
    printf("Sum: %llu\n", counter); 
    printf("Main: Program completed. Exiting.\n"); 
    pthread_exit(NULL); 
} 

, 나는 마지막에 정확한 카운터 값을 얻을 수를 PRINT 0, 나는 다음 (다중 실행)을 얻을 :

$ ./a.out 
Sum: 991 
Main: Program completed. Exiting. 
$ ./a.out 
Sum: 1000 
Main: Program completed. Exiting. 
$ ./a.out 
Sum: 962 
Main: Program completed. Exiting. 
$ ./a.out 
Sum: 938 
Main: Program completed. Exiting. 

어떤 통찰력 무슨 일이야? 인쇄 명령문을 사용하도록 설정하면 결과가 (일관되게) 올바르지 만 비활성화되고 카운터가 목표 값에 도달하지 않는 이유는 무엇입니까? 나는 pthread를 꽤 많이 사용했지만 spinlock을 직접 사용하지는 않았습니다.

도움이나 의견을 보내 주시면 감사하겠습니다.

답변

1

잠금 메서드는 실제로 아무것도 수행하지 않습니다. 인수가 값으로 전달되기 때문에 실제로 전역 잠금 값을 테스트하거나 설정하지 않습니다. 함수가 가져 오는 변수 복사본의 값만 변경하고 있습니다.

대신 spin_lock/spin_unlock 메소드가 정수 (예 : &lock)에 대한 포인터를 사용하면 코드가 작동해야합니다.

부하가 걸리는 printf는 아마도 printf가 threadsafe로 간주되기 때문에 의도하지 않은 synchonisation을 유발할 수 있습니다.

+0

오, 감사합니다. 이를 반영하기 위해 내 게시물을 업데이트했습니다. – aqua