2017-12-07 45 views
5

Tôi đã làm việc trên một dự án sở thích, nơi mutexes đã được hành xử bí ẩn. Tôi đun sôi nó xuống trường hợp thử nghiệm này rõ ràng là nên bế tắc.Tại sao liên kết gcc không có cờ lpthread?

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

int main() { 
    pthread_mutex_t test; 
    pthread_mutex_init(&test, NULL); 
    pthread_mutex_lock(&test); 
    pthread_mutex_lock(&test); 
    printf("Took lock twice\n"); 
    return 0; 
} 

Tuy nhiên, khi tôi biên dịch mà không có sự -lpthread cờ, không chỉ chương trình vẫn biên dịch và liên kết, nó cũng chạy mà không deadlocking. Tại sao?

gcc pthread_break.c -o pthread_test 
./pthread_test 
Took lock twice 

Biên soạn với -lpthread cờ mang lại kết quả mong đợi:

gcc pthread_break.c -o pthread_test -lpthread 
./pthread_test 
    <- deadlocked here 

Tôi đang chạy phiên bản GCC 7.2.0.

+3

Bản sao có thể có của [là pthread trong glibc.so được thực hiện bởi biểu tượng yếu để cung cấp chức năng stubread stub?] (Https://stackoverflow.com/questions/21092601/is-pthread-in-glibc-so-implemented-by -weak-symbol-to-offer-pthread-stub-functi) – Lanting

+0

Câu trả lời liên quan nhưng không phải là câu hỏi trùng lặp. –

+1

Bạn đang sử dụng nền tảng nào? Có thể thư viện chuẩn chứa các hàm Pthread hoặc các phiên bản giả luôn báo cáo lỗi "chưa được thực hiện". Bạn có kiểm tra cẩn thận mọi mã thoát và báo cáo lỗi cẩn thận không? –

Trả lời

1

Câu hỏi đặt ra dường như thiếu thông tin - nhưng có vẻ như rằng có hai lựa chọn:

Thứ nhất, mutex được bắt đầu với PTHREAD_MUTEX_RECURSIVE mà sẽ cho phép đấu khóa của một mutex - một số ref được quản lý và mutex là chỉ giải phóng khi số ref là 0. điều này có nghĩa là người ta có thể khóa cùng một mutex nhiều lần trong cùng một luồng, nhưng để giải phóng nó, người ta phải cung cấp cùng một lượng un-locks. Thứ hai, là gcc trong phiên bản này chỉ thực hiện các hàm cho các hàm pthread - có nghĩa là nếu bạn không thêm -lpthread thư viện, việc liên kết chỉ thị các chức năng khóa sẽ không được triển khai. điều này được hỗ trợ bởi thực tế là sau khi bạn đã thêm tùy chọn, bế tắc sẽ xuất hiện.

Tôi sẽ thử và đi qua nguồn GCC để xác minh rằng đây thực sự là kết quả của tùy chọn thứ hai - sẽ thêm bản cập nhật. Chú ý: Nó luôn luôn được khuyến khích để liên kết các thư viện đặc biệt vì nó cho phép kiểm soát kết quả - dự phòng trên GCC hỗ trợ nội bộ có thể gây ra hành vi bất ngờ, như đã thấy ở trên.

Các vấn đề liên quan