Tôi đang viết một máy chủ socket miền Unix cho Linux.Làm cách nào để biết liệu có quá trình nào bị ràng buộc với một ổ cắm miền Unix không?
Tính đặc thù của ổ cắm miền Unix Tôi nhanh chóng phát hiện ra rằng, trong khi tạo ổ cắm Unix đang nghe tạo mục nhập hệ thống tệp phù hợp, đóng chốt không loại bỏ nó. Hơn nữa, cho đến khi mục nhập hệ thống tập tin được gỡ bỏ thủ công, không thể để bind()
một ổ cắm vào cùng một đường dẫn nữa: bind()
không thành công với EADDRINUSE
nếu đường dẫn được đưa ra đã tồn tại trong hệ thống tệp.
Kết quả là, mục nhập hệ thống tệp của socket cần phải được tắt unlink()
'bật tắt máy chủ để tránh bị EADDRINUSE
khởi động lại máy chủ. Tuy nhiên, điều này không phải lúc nào cũng được thực hiện (nghĩa là: máy chủ bị lỗi). Hầu hết các câu hỏi thường gặp, bài đăng trên diễn đàn, Q & Một trang web tôi đã tìm thấy chỉ tư vấn, như một giải pháp, để unlink()
ổ cắm trước khi gọi bind()
. Trong trường hợp này tuy nhiên, nó trở nên mong muốn để biết liệu một quá trình được ràng buộc vào ổ cắm này trước khi unlink()
'ing nó.
Thực tế, unlink()
'đang nhập một ổ cắm Unix trong khi quá trình vẫn bị ràng buộc với nó và sau đó tạo lại ổ cắm nghe không gây ra bất kỳ lỗi nào. Kết quả là, tuy nhiên, quá trình máy chủ cũ vẫn chạy nhưng không thể truy cập được: ổ cắm nghe cũ được "đeo" bởi ổ cắm mới. Hành vi này phải được tránh. Lý tưởng nhất là, bằng cách sử dụng các ổ cắm miền Unix, API socket nên tiếp xúc với cùng một hành vi "loại trừ lẫn nhau" được tiếp xúc khi gắn các cổng TCP hoặc UDP: "Tôi muốn kết nối socket S với địa chỉ A; đã bị ràng buộc với địa chỉ này, chỉ cần khiếu nại! "Rất tiếc, đây không phải là trường hợp ...
Có cách nào để thực thi hành vi" loại trừ lẫn nhau "này không? Hoặc, với một đường dẫn hệ thống tập tin, có cách nào để biết, thông qua API socket, cho dù bất kỳ quá trình nào trên hệ thống đều có một ổ cắm miền Unix được liên kết với đường dẫn này không? Tôi có nên sử dụng đồng bộ hóa nguyên thủy bên ngoài với API socket (flock()
, ...) không? Hay tôi đang thiếu một cái gì đó?
Cảm ơn đề xuất của bạn.
Lưu ý: Không gian tên trừu tượng của Linux Các ổ cắm Unix dường như giải quyết vấn đề này, vì không có mục nhập hệ thống tệp nào vào unlink()
. Tuy nhiên, máy chủ tôi đang viết nhằm mục đích là chung chung: nó phải mạnh mẽ chống lại cả hai loại ổ cắm miền Unix, vì tôi không chịu trách nhiệm về việc chọn địa chỉ nghe.
Cảm ơn câu trả lời của bạn. Sử dụng một hệ thống lockfile truyền thống được thừa nhận là cách an toàn nhất để đi. Ngoài ra, để biết liệu một hệ thống phát hiện dịch vụ có quá tải hay không: trớ trêu thay, máy chủ này được dự định là một phần của hệ thống khám phá dịch vụ (hệ thống "đăng ký" dịch vụ có vẻ phù hợp hơn). Điêu nay co thể trả lơi câu hỏi của bạn ;-) –