Bạn dường như nhầm lẫn ánh xạ bộ nhớ với các tệp trong các hệ thống tệp nằm trong bộ nhớ, cùng với các khái niệm khác như cách các quy trình duy trì quyền truy cập vào các tệp ngay cả khi chúng di chuyển xung quanh.
Tôi sẽ đi từng câu hỏi để xem liệu tôi có thể làm sáng tỏ mọi thứ không.
- Giả sử tôi duyệt đến một thư mục trong hệ thống tệp của mình và có một tệp trong thư mục này. Có thể tệp này trỏ đến một vùng trong bộ nhớ chính, thay vì chỉ vào một vùng trong đĩa?
Nó chỉ vào bộ nhớ chính nếu nó nằm trên một hệ thống tệp nằm trong bộ nhớ, như các Procfs thường được gắn trên / Proc hoặc sysfs trên / sys hoặc tmpfs đôi khi trên / tmp.
- Nếu điều này là có thể, đây có phải là cái mà chúng ta gọi là 'tệp ánh xạ bộ nhớ' không?
Không giống như stephen-kitt đã nói, "ánh xạ bộ nhớ" đề cập đến một cách để truy cập một tệp bằng cách "ánh xạ" nó vào bộ nhớ chính và làm việc với nó ở đó thay vì đọc và viết các đoạn tại một thời điểm thông qua các hàm như read () và viết ().
- Ý nghĩa của việc di chuyển tệp như vậy xung quanh hệ thống tệp (nghĩa là chuyển tệp đó từ thư mục này sang thư mục khác)? Điều tôi hiểu là, vì tệp được ánh xạ bộ nhớ, quá trình tương tác với tệp luôn ghi vào vùng được xác định trước của bộ nhớ chính và khi chúng tôi mở tệp đó (ví dụ: sử dụng vim), chúng tôi đọc vùng đó bộ nhớ chính (vì vậy, không có đĩa liên quan). Do đó, bất kể chúng ta di chuyển tệp ở đâu, nó sẽ luôn hoạt động chính xác phải không? Nếu có, việc di chuyển tệp xung quanh hệ thống tệp có ý nghĩa gì không?
Nếu bạn di chuyển nó trong cùng một hệ thống tập tin, bạn thực sự chỉ di chuyển xung quanh một tham chiếu, một nút từ thư mục này sang thư mục khác. Nếu có các chương trình đã mở tệp này, chúng vẫn sẽ truy cập vào cùng một tệp vì chúng đã có sẵn nút inode thông qua bộ mô tả tệp. Đây là những gì đã xảy ra với tệp table_name.idb mà bạn đã đề cập trong một nhận xét.
- Có một lệnh sẽ cho biết nếu một tập tin được ánh xạ bộ nhớ?
Wossname đã trả lời điều này cho các tệp ánh xạ bộ nhớ. lsof
sẽ cho bạn biết các quá trình có ánh xạ bộ nhớ tập tin.
Để biết nếu một tệp nằm trong hệ thống tệp nằm trong bộ nhớ, bạn có thể sử dụng df
hoặc
mount
liệt kê các hệ thống tệp và các điểm gắn kết của chúng. Bạn chỉ cần biết loại hệ thống tập tin nào nằm trong bộ nhớ bằng cách tìm kiếm chúng (ví dụ như trong wikipedia).
- Cuối cùng, nếu tôi mở tệp ánh xạ bộ nhớ bằng vim, hãy thực hiện một số thay đổi trên đó và lưu và đóng vim, điều gì sẽ xảy ra? Những thay đổi của tôi chỉ đơn giản sẽ được ghi vào bộ nhớ chính? Nếu đó là trường hợp, các quá trình khác sử dụng tệp này sẽ thấy những thay đổi tôi vừa thực hiện? Theo kinh nghiệm của tôi, các quy trình khác không thấy các thay đổi tôi đã thực hiện đối với tệp khi tôi thực hiện một số thay đổi trên tệp bằng vim. Lý do cho điều này là gì?
Cá nhân, tôi đã không sử dụng mmap
chức năng này trong một chương trình C, nhưng theo tôi hiểu nó từ việc lướt qua man mmap
và info mmap
, không có phép thuật nào liên quan đến việc duy trì đồng bộ hóa trong bộ nhớ. Ở dạng cơ bản, gọi mmap sao chép nội dung tệp vào bộ nhớ và msync
được sử dụng để ghi lại từ bộ nhớ vào đĩa. Nếu tệp trên đĩa thay đổi, không có gì để phát hiện điều đó và tự động sửa đổi biểu diễn trong bộ nhớ trong tất cả các quy trình ánh xạ tệp.
EDIT: Hóa ra mmap () thực sự cố gắng giữ đồng bộ hóa trong bộ nhớ trong một số điều kiện. Nếu bản đồ chỉ được đọc từ, nó sẽ được giữ đồng bộ ngay cả khi các quá trình khác ghi vào tệp. Nếu nó được ghi vào (bằng cách gán cho vùng nhớ), điều gì xảy ra tùy thuộc vào cờ nào trong số các cờ MAP_SHARED hoặc MAP_PRIVATE bắt buộc được cung cấp cho mmap (). Nếu MAP_PRIVATE được cung cấp, bản đồ sẽ chuyển từ biểu diễn trên đĩa và dừng đồng bộ hóa cho đến khi bạn sử dụng msync (). Nếu MAP_SHARED được cung cấp, thì các bản cập nhật sẽ được hiển thị cho các quy trình khác có tệp được ánh xạ, cũng như (mặc dù điều này không ngay lập tức) đại diện trên đĩa.
Tôi vừa mở vim trên một tệp hiện có e
, và chạy lệnh :w
, trong khi inotifywait -m .
chạy trong một thiết bị đầu cuối khác. Trong số một số bit lạ, đây là phần quan trọng tôi nhận được inotifywait
.
./ MOVED_FROM e
./ MOVED_TO e~
./ CREATE e
./ OPEN e
./ MODIFY e
./ CLOSE_WRITE,CLOSE e
./ ATTRIB e
./ ATTRIB e
./ DELETE e~
Vim tạo một tệp mới và xóa tệp cũ. Tại sao nó làm điều này thay vì sửa đổi tệp nằm ngoài phạm vi của câu hỏi này, nhưng vấn đề là đây là một tệp mới và do đó có một nút mới.
Bây giờ, ý nghĩa của các quá trình khác khi sử dụng tệp này là gì? Nếu bạn có nghĩa là các quy trình đã mở tệp trong khi bạn đang thực hiện việc này, thì họ sẽ không thấy các thay đổi. Điều này là do, mặc dù họ đã mở một tệp có cùng đường dẫn, nhưng chúng không phải là cùng một tệp. Nếu bạn có nghĩa là các quy trình có thể mở tệp sau khi bạn thực hiện việc này, thì có, họ sẽ thấy các thay đổi. Họ sẽ mở tệp mới mà bạn đã tạo.
Điều quan trọng cần lưu ý là mặc dù các chương trình dường như có một tệp được mở trên giao diện người dùng, nhưng điều đó không có nghĩa là chúng sẽ giữ tệp mở trong quá trình này. Vim là một ví dụ về điều này, như được hiển thị ở trên.