2012-04-21 21 views
5

Tôi đang sử dụng pthread_mutex_trylock để khóa mutex trên cấu trúc sao cho chỉ có thể truy cập/sửa đổi một chuỗi duy nhất tại một thời điểm nhất định. Nếu mutex đã bị khóa tôi chỉ trở về từ các thói quen hơn là xếp hàng/chặn.khối `pthread_mutex_trylock` khi được gọi bởi hai luồng cùng một lúc

Đây là một phác thảo cơ bản của mã của tôi:

typedef struct { 
    pthread_mutex_t m; 
} myStruct; 

void setupStruct(myStruct* struc) { 
    pthread_mutex_init(&struc->m, NULL); 
} 

void structOp(myStruct* struc) { 

    printf("structOp(): Trying to lock\n"); 

    if(pthread_mutex_trylock(&struc->m) != 0) { 
     printf("structOp(): Lock failed\n"); 
     return; 
    } else { 
     printf("structOp(): Locked\n"); 
     // do some stuff to struct 
     pthread_mutex_unlock(&struc->m); 
    } 
} 

Các struct được khởi tạo một lần như thế này:

myStruct* struc = malloc(sizeof(struc)); 
setupStruct(struc); 

Tuy nhiên, đôi khi hai luồng gọi một thói quen cùng một lúc cả hai cuộc gọi đến trylock dường như bị chặn. Tôi giả định điều này bởi vì nó in "cố gắng khóa" cho cả hai chủ đề cùng một lúc, nhưng không in có hay không mutex đã bị khóa. Ban đầu, tôi gặp vấn đề này với pthread_mutex_lock vì vậy đã thử phiên bản không chặn vì lý do này, nhưng dường như nó vẫn bị chặn.

Điều này không phải lúc nào cũng xảy ra nhưng khi nó luôn là trước tiên, hãy gọi số cuộc gọi đến thường lệ. Nếu hai cuộc gọi đầu tiên chạy tốt, thì các cuộc gọi tiếp theo cũng hoạt động tốt.

Có lý do nào để chặn không? Tôi có nhận thấy không chính xác việc chặn này do một số vấn đề khác không? Tôi có thể đăng các phần khác của mã của tôi nếu vấn đề có thể nằm ở nơi khác.

+1

không có lý do cho điều này để ngăn chặn, AFAIK. Có thể có gì đó không ổn ở nơi khác. – Mat

+1

Cuộc gọi setupStruct() nào? Nó không được gọi nhiều hơn một lần, cơ hội nào? –

+0

Nó chắc chắn chỉ được gọi một lần, ngay trước khi các chủ đề mới được bắt đầu. Tôi nghĩ nếu có vấn đề thì rất có thể với việc sử dụng con trỏ của tôi. Những điều này có đúng không? Tôi đang phân bổ cấu trúc với 'myStruct * struc = malloc (sizeof (struc));'. Tôi sẽ cập nhật câu hỏi với thông tin này. – Matt

Trả lời

8

Dòng này là sai:

myStruct* struc = malloc(sizeof(struc)); 

Nó không alloate đủ bộ nhớ, vì vậy có lẽ bạn đang làm dơ bẩn/tái sử dụng bộ nhớ nơi mà bạn truy cập mutex. Sử dụng sizeof(struc) cấp phát bộ nhớ cho các loại struc, và loại struc là một myStruct*, vì vậy bạn chỉ cấp phát bộ nhớ đủ để giữ một con trỏ (ielikely chỉ 4 hoặc 8 byte)

Bạn nên làm

myStruct* struc = malloc(sizeof *struc); 

hoặc

myStruct* struc = malloc(sizeof(myStruct)); 
+0

Wow, tôi đã phân bổ các cấu trúc của mình sai trong một thời gian dài .. cảm ơn vì đã giải thích! – Matt

0

Đây là một số loại vấn đề về thời gian hoặc tham nhũng bộ nhớ. Dù bằng cách nào nó không liên quan đến mã bạn đăng, vì vậy không có cách nào để trả lời câu hỏi này.

Nếu hệ điều hành của bạn hỗ trợ valgrind, hãy kiểm tra ứng dụng của bạn bằng các mô-đun memcheckhelgrind.