2009-11-22 26 views
6

Tôi có một thư viện được chia sẻ (.so) mà tôi tải trước trước khi thực hiện một ứng dụng và tôi có một vài cấu trúc dữ liệu chung trong thư viện được chia sẻ mà ứng dụng sử dụng. Ứng dụng có thể tạo các quy trình khác nói bằng fork() và các quy trình này có thể cập nhật cấu trúc dữ liệu toàn cục trong thư viện được chia sẻ. Tôi muốn giữ một cái nhìn nhất quán về các cấu trúc dữ liệu toàn cầu này trên tất cả các quy trình. Có cách nào tôi có thể thực hiện điều này trong Linux?Làm thế nào để chia sẻ các biến toàn cầu trong một thư viện được chia sẻ (.so) trong các trường hợp của cùng một quá trình sử dụng thư viện được chia sẻ trong Linux?

Tôi đã thử sử dụng lệnh shm_ * và mmap() để ánh xạ dữ liệu chung của thư viện được chia sẻ thành một phân đoạn được chia sẻ nhưng nó không hoạt động.

Trả lời

0

Cách tạo một đường ống đơn giản ở vị trí thư mục đã biết, sau đó nhận các quy trình khác để fopen đường ống để đọc/viết la fread/fwrite tương ứng, để chia sẻ dữ liệu ... đi qua đường ống theo cách không gây tham nhũng trong trường hợp này. Ở trên bạn đã đề cập bằng cách sử dụng bộ nhớ chia sẻ shm_ và mmap được gắn với quá trình, khi bạn ngã ba mã, đó là không có vấn đề kể từ khi fork'd mã là một phần của quá trình ban đầu! Hi vọng điêu nay co ich.

Trân trọng, Tom.

8

Để cụm từ này rõ ràng nhất: bạn không thể làm chính xác những gì bạn đã yêu cầu. Linux không hỗ trợ chia sẻ các biến toàn cục do trình liên kết đặt ra. Bộ nhớ đó sẽ nằm trong khoảng trống được ánh xạ tới không hoán đổi.

Một công thức chung tôi có thể cung cấp là thế này:

  1. định nghĩa một struct đó đưa ra dữ liệu của bạn. Không có con trỏ! Chỉ cần bù đắp.
  2. quy trình đầu tiên tạo tệp trong/tmp, đặt quyền truy cập rw nếu cần. Mở, mmap với MAP_SHARED.
  3. Quy trình tiếp theo cũng mở, mmap với MAP_SHARED.
  4. mọi người đều sử dụng cấu trúc để tìm các phần họ tham chiếu, đọc hoặc viết.
  5. Tìm hiểu đồng thời!

Nếu bạn thực sự chỉ quan tâm đến cha mẹ và con của nó, bạn có thể sử dụng ánh xạ ẩn danh và không bận tâm đến tệp và bạn có thể lưu trữ vị trí của bản đồ trong toàn cầu (có thể đọc được trẽ con).

4

Nếu bạn chỉ muốn chia sẻ dữ liệu với và giữa các quá trình con cháu (và không phải với các quá trình tùy ý được khởi động riêng rẽ, chỉ xảy ra liên kết đến cùng một thư viện được chia sẻ), thì cách dễ nhất để thực hiện điều này là thư viện tạo một ánh xạ với mmap() trong hàm hàm dựng (được gọi khi thư viện ban đầu được nạp trong tiến trình cha).

Vượt qua MAP_ANONYMOUSMAP_SHARED cờ đến mmap - điều này có nghĩa là quá trình con kế thừa ánh xạ sẽ có ánh xạ được chia sẻ với cha mẹ (và các trẻ khác). Thư viện sau đó sẽ lưu trữ các cấu trúc dữ liệu được chia sẻ trong phân đoạn bộ nhớ mmaped đó (giống như bộ nhớ được trả về từ malloc). Rõ ràng bạn có thể cần một số loại khóa.

Chức năng xây dựng cho thư viện có thể được chỉ định bằng thuộc tính chức năng gcc__constructor__.

Bạn không cần phải lo lắng về việc dọn dẹp loại bộ nhớ dùng chung này - khi quá trình cuối cùng có lối thoát bản đồ ẩn danh, bộ nhớ sẽ được dọn sạch.

+0

Điều này không làm những gì OP yêu cầu: chia sẻ, hai chiều, các biến toàn cầu. – bmargulies

+0

Chắc chắn nó, nếu những biến toàn cầu được lưu trữ trong bản đồ được chia sẻ (điều này cũng có nghĩa là các biến toàn cầu thực sự cần phải là con trỏ, nhưng đó chỉ là một chi tiết thực hiện). – caf

+0

Nó sẽ làm việc trên một ngã ba() nhưng không phải là một exec() (nói rằng quá trình mới sử dụng cùng một thư viện), do đó, sẽ không làm việc trong trường hợp chung – MarkR

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