2017-10-18 1 views
0

바쁜 대기없이 뮤텍스 잠금을 구현하기 위해 대학 과제를 받았습니다. 나는 그것을 구현하려고 노력하지만 많은 성공을 거두지 않고있다. 때로는, 그냥 매달려 계속 다른 시간 세그먼트 화 오버플로를 throw하지만, 내가 완벽하게 때마다 실행되는 gdb에서 실행할 때.바쁜 대기없이 뮤텍스 잠금 구현

mutex.c

#define _GNU_SOURCE 

#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 
#include <signal.h> 
#include <stdbool.h> 
#include <sys/syscall.h> 
#include "stack.h" 

#define NUM_THREADS 2 

// shared data structure 
int sum = 0; 

struct Stack waiting_q; 

bool mutex_locked = false; 

void * got_signal(int x) { return NULL; } 

void acquire() 
{ 
    bool first_time = true; 
    while (!__sync_bool_compare_and_swap(&mutex_locked, false, true)) 
    { 
     if (first_time) 
     { 
      push(&waiting_q, pthread_self()); 
      first_time = false; 
     } 
     printf("%ld is waiting for mutex\n", syscall(SYS_gettid)); 
     pause(); 
    } 
    printf("Mutex acquired by %ld\n", syscall(SYS_gettid)); 
} 

void release() 
{ 
    int thread_r = pop(&waiting_q); 
    if (waiting_q.size != 0 && thread_r != INT_MIN) 
     pthread_kill(thread_r, SIGCONT); 

    mutex_locked = false; 
    printf("Mutex released by = %ld\n", syscall(SYS_gettid)); 
} 

void * work() 
{ 
    acquire(); 

    for (int i = 0; i < 10000; i++) 
    { 
     sum = sum + 1; 
    } 
    release(); 
    return NULL; 
} 

int main() 
{ 
    init_stack(&waiting_q); 
    pthread_t threads[NUM_THREADS]; 
    for (int i = 0; i < NUM_THREADS; i++) 
    { 
     int rc = pthread_create(&threads[i], NULL, work, NULL); 
     if (rc != 0) 
      printf("Error creating thread\n"); 
    } 

    for (int i = 0; i < NUM_THREADS; i++) 
    { 
     pthread_join(threads[i], NULL); 
    } 

    printf("Value of Sum = %d\n", sum); 
    return 0; 
} 

stack.h 뮤텍스 구현에서 Stack 데이터 구조에

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

struct Node{ 
    struct Node * next; 
    pthread_t x; 
}; 

struct Stack{ 
    struct Node * head; 
    int size; 
}; 

void push(struct Stack * s, pthread_t n) 
{ 
    struct Node * new_head = malloc(sizeof(struct Node)); 
    new_head->next = s->head; 
    new_head->x = n; 
    s->head = new_head; 
    s->size++; 
} 

pthread_t pop(struct Stack * s) 
{ 
    pthread_t rc = INT_MIN; 
    if (s->head != NULL) 
    { 
     rc = s->head->x; 
     struct Node * next = s->head->next; 
     free(s->head); 
     s->head = next; 
     return rc; 
    } 
    s->size--; 
    return rc; 
} 

void init_stack(struct Stack * s) 
{ 
    s->head = 0; 
    s->size = 0; 
} 
+0

'-fsanitize = undefined, address'를 컴파일러와 링커에 전달해보십시오. 운이 좋으면 더 도움이되는 결과물을 얻을 수 있습니다. – nwp

+0

@nwp 완전히 멈추거나 제대로 작동합니다. – AhmedBilal

+1

'while' 루프 안에'push '를 넣으면 엄청난 양의 푸시가 발생할 수 있습니다. 또한,'push'와'pop'의 코드는 쓰레드에 안전하지 않은 것 같습니다. 다른 스레드가 새로운'head'를 추가하는 것처럼'free (s-> head)'를한다면? –

답변

0

액세스가 동기화되지 않습니다.

여러 스레드가 동시에 acquire mutex를 시도하여 waiting_q에 동시에 액세스 할 수 있습니다. 마찬가지로 해제 스레드의 pop() 액세스는 waiting_q과 획득 스레드의 액세스가 동기화되지 않습니다.

Stack에있는이 데이터 경주는 아마도 segfault의 원인 일 가능성이 큽니다.

+0

실제로 모든 데이터 구조가 작동합니다. 나중에 잠자기 중지 한 스레드를 추적하고 싶습니다. – AhmedBilal

+0

@AhmedBilal 문제는 데이터 구조가 아니라 동기화 부족입니다. 다른 (스레드 비 안전) 데이터 구조와 유사한 충돌이 발생합니다. – ComicSansMS

+0

어떻게 해결할 수 있습니까? – AhmedBilal