Khóa tệp thực thi: Windows thì có, Linux thì không. Tại sao?


82

Tôi nhận thấy khi tệp được thực thi trên Windows (.exe hoặc .dll), tệp đó bị khóa và không thể xóa, di chuyển hoặc sửa đổi.

Mặt khác, Linux không khóa các tệp đang thực thi và bạn có thể xóa, di chuyển hoặc sửa đổi chúng.

Tại sao Windows khóa trong khi Linux thì không? Có một lợi thế để khóa?


6
Có một tiện ích được gọi là WhoLockMe bổ sung một mục menu vào menu ngữ cảnh trong trình khám phá, tiện ích này có thể hiển thị (các) quy trình khóa một tệp nhất định. Cực kỳ hữu ích khi bạn gặp lỗi khóa tệp kỳ lạ. Chỉnh sửa: Tôi biết rằng đây không phải là câu trả lời cho câu hỏi, nhưng tôi nghĩ rằng nó đủ hữu ích trong bối cảnh để đảm bảo một câu trả lời riêng biệt (đối lập với chỉ một bình luận).
JesperE 13/10/08

Câu trả lời:


106

Linux có cơ chế đếm tham chiếu, vì vậy bạn có thể xóa tệp trong khi tệp đang thực thi và nó sẽ tiếp tục tồn tại miễn là một số quy trình (Đã mở trước đó) có một xử lý mở cho nó. Mục nhập thư mục cho tệp sẽ bị xóa khi bạn xóa nó, vì vậy nó không thể mở được nữa, nhưng các quy trình đã sử dụng tệp này vẫn có thể sử dụng nó. Khi tất cả các quy trình sử dụng tệp này kết thúc, tệp sẽ tự động bị xóa.

Windows không có khả năng này, vì vậy nó buộc phải khóa tệp cho đến khi tất cả các quá trình thực thi từ nó kết thúc.

Tôi tin rằng hành vi Linux là thích hợp hơn. Có thể có một số lý do kiến ​​trúc sâu xa, nhưng lý do chính (và đơn giản) mà tôi thấy thuyết phục nhất là trong Windows, đôi khi bạn không thể xóa một tệp, bạn không biết tại sao và tất cả những gì bạn biết là một số quy trình đang giữ nó trong sử dụng. Trong Linux, điều đó không bao giờ xảy ra.


2
Lưu ý rằng bạn có thể sử dụng một công cụ như Process Explorer trong Windows để xem tiến trình nào đang sử dụng tệp / thư mục.
J c

14
Một lý do thực tế có lợi cho hành vi của Linux là bạn có thể cập nhật hệ điều hành và phần mềm khác trên hệ thống khi nó đang chạy và không bao giờ / hiếm khi khởi động lại (bạn thậm chí có thể chuyển đổi hạt nhân đang chạy mà không cần khởi động lại, nó chỉ được gọi là cho các ứng dụng quan trọng về thời gian hoạt động).
joelhardi 13/10/08

6
"Windows không có khả năng này" ... bạn có chắc không? Kernel NT dựa trên việc tính toán lại các đối tượng có tay cầm và tham chiếu.
Adam Mitz 13/10/08

10
Windows thực sự có 3 bit mà bạn có thể đặt để xác định những gì một quá trình khác có thể làm với một tệp khi nó đang mở. Một tệp có thể bị xóa trong khi nó đang mở nếu FILE_SHARE_DELETEbit được đặt. Tôi không nghĩ rằng trình tải PE (tải EXE và DLL) đặt bit này. Các xử lý được tính là tham chiếu và khi xóa tệp sẽ biến mất khi xử lý cuối cùng bị bỏ, nhưng sự khác biệt giữa điều đó và Unix là NT sẽ chặn tạo tệp mới có cùng tên khi điều này xảy ra.
asveikau

2
Những gì comonad nói là hoàn toàn sai, NTFS tất nhiên sử dụng Liên kết cứng và luôn luôn như vậy, các liên kết tượng trưng đã được thêm vào Windows Vista. Cũng hoàn toàn sai lầm khi Windows không sử dụng ref copunting, nó chỉ đọc các API như CreateFile wher eit đã nói rõ ràng trong trường hợp nào các tệp có thể xóa được và như vậy. Và đó cũng là nơi thích hợp cho câu trả lời thực sự cho câu hỏi: CreateFile có đối số claled dwShareMode kiểm soát việc khóa bắt buộc các tệp đã mở và cho phép các ứng dụng quyết định. Giá trị mặc định là một khóa độc quyền ...
Thorsten Schöning

29

Theo như tôi biết, Linux không thực thi khóa khi họ đang chạy - tuy nhiên, nó khóa inode . Điều này có nghĩa là bạn có thể xóa "tệp" nhưng inode vẫn còn trên hệ thống tệp, không bị ảnh hưởng và tất cả những gì bạn thực sự xóa là một liên kết.

Các chương trình Unix luôn sử dụng cách suy nghĩ này về hệ thống tệp, tạo một tệp tạm thời, mở nó, xóa tên. Tệp của bạn vẫn tồn tại nhưng tên được giải phóng cho người khác sử dụng và không ai khác có thể nhìn thấy nó.


"mọi lúc"? Có ví dụ nào không?
Mez 13/10/08

4
Hỏi google về "tệp tạm thời an toàn unix" và bạn sẽ tìm thấy đủ mô tả về kỹ thuật này để chứng tỏ rằng nó nổi tiếng và được sử dụng phổ biến. Mặc dù tôi không có bất kỳ ví dụ cụ thể nào để đưa ra, nhưng tôi dám khẳng định rằng bất kỳ ứng dụng nào có ý thức bảo mật sử dụng tệp tạm thời đều làm được điều này.
Dave Sherohman 13/10/08

26

Linux không khóa các tệp. Nếu bạn cố gắng ghi đè lên tệp đang thực thi, bạn sẽ nhận được "ETXTBUSY" (Tệp văn bản bận). Tuy nhiên, bạn có thể xóa tệp và hạt nhân sẽ xóa tệp khi tham chiếu cuối cùng đến nó bị xóa. (Nếu máy không tắt hoàn toàn, các tệp này là nguyên nhân gây ra thông báo "Đã xóa inode không có thời gian d-time" khi hệ thống tệp được kiểm tra, chúng chưa bị xóa hoàn toàn, vì một quá trình đang chạy có tham chiếu đến chúng, và bây giờ họ đang có.)

Điều này có một số ưu điểm chính, bạn có thể nâng cấp một quy trình đang chạy, bằng cách xóa tệp thực thi, thay thế nó, sau đó khởi động lại quy trình. Ngay cả init cũng có thể được nâng cấp như thế này, thay thế tệp thực thi và gửi tín hiệu cho nó và nó sẽ tự thực thi lại () mà không yêu cầu khởi động lại. (Thường được thực hiện tự động bởi hệ thống quản lý gói của bạn như một phần của quá trình nâng cấp)

Trong cửa sổ, việc thay thế một tệp đang được sử dụng dường như là một rắc rối lớn, thường yêu cầu khởi động lại để đảm bảo không có quy trình nào đang chạy.

Có thể có một số vấn đề, chẳng hạn như nếu bạn có một tệp nhật ký cực kỳ lớn và bạn xóa nó, nhưng quên nói với quá trình đang ghi nhật ký vào tệp đó để mở lại tệp, nó sẽ giữ tham chiếu và bạn sẽ tự hỏi tại sao đĩa của bạn đột nhiên không nhận được nhiều dung lượng trống hơn.

Bạn cũng có thể sử dụng thủ thuật này trong linux cho các tệp tạm thời. mở tệp, xóa nó, sau đó tiếp tục sử dụng tệp. Khi quá trình của bạn thoát (vì bất kỳ lý do gì - ngay cả khi mất điện), tệp sẽ bị xóa.

Các chương trình như lsof và fuser (hoặc chỉ cần dò tìm trong / proc // fd) có thể cho bạn biết quy trình nào có các tệp đang mở mà không còn tên.


6

Tôi nghĩ linux / unix không sử dụng cùng một cơ chế khóa vì chúng được xây dựng từ đầu như một hệ thống nhiều người dùng - điều này sẽ mong đợi khả năng nhiều người dùng sử dụng cùng một tệp, thậm chí có thể cho các mục đích khác nhau.

Có một lợi thế để khóa? Chà, nó có thể làm giảm số lượng con trỏ mà Hệ điều hành sẽ phải quản lý, nhưng hiện tại, số tiền tiết kiệm được là không đáng kể. Ưu điểm lớn nhất mà tôi có thể nghĩ đến để khóa là điều này: bạn tiết kiệm được một số sự mơ hồ có thể xem của người dùng. Nếu người dùng a đang chạy một tệp nhị phân và người dùng b xóa nó, thì tệp thực sự phải tồn tại cho đến khi quá trình của người dùng A hoàn tất. Tuy nhiên, nếu Người dùng B hoặc bất kỳ người dùng nào khác tìm nó trên hệ thống tệp, họ sẽ không thể tìm thấy nó - nhưng nó sẽ tiếp tục chiếm dung lượng. Không thực sự là một mối quan tâm lớn đối với tôi.

Tôi nghĩ phần lớn là câu hỏi về khả năng tương thích ngược với hệ thống tệp của window.


"Windows" trong ngữ cảnh này là dòng Windows NT. Điều này được thiết kế như một phiên bản kế thừa nhiều người dùng cho Windows 3.11 một người dùng. So sánh với Unix, là phiên bản kế thừa dành cho một người dùng của Multics.
MSalters

6

Tôi nghĩ bạn quá tuyệt đối về Windows. Thông thường, nó không phân bổ không gian hoán đổi cho phần mã của tệp thực thi. Thay vào đó, nó giữ một khóa trên các tệp tin & DLL. Nếu các trang mã bị loại bỏ là cần thiết một lần nữa, chúng chỉ cần tải lại. Nhưng với / SWAPRUN, các trang này được giữ ở dạng hoán đổi. Điều này được sử dụng cho các tệp thực thi trên CD hoặc ổ đĩa mạng. Do đó, các cửa sổ không cần phải khóa các tệp này.

Đối với .NET, hãy xem Shadow Copy .


1

Nếu mã được thực thi trong một tệp có bị khóa hay không là do thiết kế quyết định và MS chỉ đơn giản là quyết định khóa, bởi vì nó có lợi thế rõ ràng trong thực tế: Bằng cách đó, bạn không cần biết mã trong phiên bản nào được ứng dụng nào sử dụng. Đây là một vấn đề lớn với hành vi mặc định của Linux, mà hầu hết mọi người đều bỏ qua. Nếu các lib trên toàn hệ thống được thay thế, bạn không thể dễ dàng biết ứng dụng nào sử dụng mã của các lib như vậy, hầu hết những lần tốt nhất bạn có thể nhận được là trình quản lý gói biết một số người dùng của các lib đó và khởi động lại chúng. Nhưng điều đó chỉ hoạt động đối với những thứ chung chung và biết rõ như có thể là Postgres và các lib của nó hoặc tương tự. Các tình huống thú vị hơn là nếu bạn phát triển ứng dụng của riêng mình chống lại một số lib của bên thứ 3 và những ứng dụng đó bị thay thế, bởi vì hầu hết các trường hợp trình quản lý gói chỉ đơn giản là không biết ứng dụng của bạn. Và đó ' Không chỉ là vấn đề của mã C gốc hoặc như vậy, nó có thể xảy ra với hầu hết mọi thứ: Chỉ cần sử dụng httpd với mod_perl và một số Perl libs được cài đặt bằng trình quản lý gói và để trình quản lý gói cập nhật những Perl lib đó vì bất kỳ lý do gì. Nó sẽ không khởi động lại httpd của bạn, đơn giản vì nó không biết các phần phụ thuộc. Có rất nhiều ví dụ như ví dụ này, đơn giản vì bất kỳ tệp nào cũng có thể chứa mã được sử dụng trong bộ nhớ trong bất kỳ thời gian chạy nào, hãy nghĩ đến Java, Python và tất cả những thứ như vậy.

Vì vậy, có lý do chính đáng để có ý kiến ​​rằng khóa tệp theo mặc định có thể là một lựa chọn tốt. Tuy nhiên, bạn không cần phải đồng ý với những lý do đó.

Vậy MS đã làm gì? Họ chỉ đơn giản là tạo ra một API để cho ứng dụng gọi điện có cơ hội quyết định xem tệp có nên bị khóa hay không, nhưng họ quyết định rằng giá trị mặc định của API này là cung cấp một khóa độc quyền cho ứng dụng gọi đầu tiên. Hãy xem API xung quanh CreateFiledwShareModeđối số của nó . Đó là lý do tại sao bạn không thể xóa tệp đang được sử dụng bởi một số ứng dụng, nó chỉ đơn giản là không quan tâm đến trường hợp sử dụng của bạn, sử dụng các giá trị mặc định và do đó, Windows đã khóa riêng một tệp.

Vui lòng không tin vào những người nói với bạn điều gì đó về việc Windows không sử dụng số lần tham chiếu trên HANDLEs hoặc không hỗ trợ Liên kết cứng hoặc tương tự, điều đó hoàn toàn sai. Hầu hết mọi API sử dụng HANDLEs đều ghi lại hành vi của nó liên quan đến việc đếm tham chiếu và bạn có thể dễ dàng đọc trong hầu hết các bài viết về NTFS mà nó trong chứng thư có hỗ trợ Liên kết cứng và luôn làm như vậy. Kể từ khi Windows Vista nó cũng hỗ trợ Symlinks và Hỗ trợ cho Hardlinks đã được cải thiện bằng cách cung cấp các API để đọc tất cả các API đó cho một tệp nhất định, v.v.

Ngoài ra, bạn có thể chỉ muốn xem các cấu trúc được sử dụng để mô tả tệp trong Ext4 so với cấu trúc của NTFS , chúng có rất nhiều điểm chung. Cả hai đều hoạt động với khái niệm phạm vi, phân tách dữ liệu khỏi các thuộc tính như tên tệp và inodes gần như chỉ là một tên khác của một khái niệm cũ hơn, nhưng tương tự về điều đó. Ngay cả Wikipedia cũng liệt kê cả hai hệ thống tệp trong bài viết của mình .

Thực sự có rất nhiều FUD xung quanh việc khóa tệp trong Windows so với các hệ điều hành khác trên mạng, giống như về chống phân mảnh. Một số FUD này có thể được loại trừ bằng cách đọc một chút trên Wikipedia .


Luyên thuyên về quản lý phiên bản của các phụ thuộc được chia sẻ là không liên quan. Bạn phải giải quyết những vấn đề đó ngay cả khi việc cập nhật chúng yêu cầu khởi động lại. Trên Windows, nó thậm chí còn có một cái tên: DLL hell. Hơn nữa, các hành vi thời gian chạy xung quanh nó mà bạn mô tả được xử lý hoàn toàn bởi trường hợp của Linux khi nó đã tải tệp vào bộ nhớ và nó vẫn có sẵn; ứng dụng sẽ tiếp tục chạy với phiên bản cũ cho đến khi khởi động lại, giống như khi Windows buộc khởi động lại để mở khóa tệp. Không có lợi thế trên mặt trận đó.
jpmc26

DLL hell tất nhiên là hoàn toàn thiếu điểm và chúng ta không còn những năm 90 nữa, chỉ cần đọc về những thứ đại loại như vậy WinSxS. Ngoài ra, không phải là tải mọi thứ vào bộ nhớ và giữ chúng ở đó, Windows làm chính xác điều đó nếu cần, mà là biết và quyết định xem tệp có nên được thay thế hay không và ai chịu trách nhiệm quyết định điều đó. Windows-API chỉ đơn giản là cho phép người dùng đầu tiên của tệp quyết định và điều đó rất có ý nghĩa.
Thorsten Schöning

Nhưng đó là quan điểm của tôi: quyết định phiên bản DLL sẽ sử dụng là một phần của DLL hell. Gọi nó là "địa ngục phụ thuộc" nếu bạn muốn phân biệt với một số hành vi mang phong cách riêng cũ của Windows. Mặc dù vậy, mặc định khóa các tệp thực thi không giúp quản lý các phần phụ thuộc được chia sẻ. Ở tất cả. Những thứ phụ thuộc vào một tệp cụ thể thậm chí có thể không chạy khi bạn cố gắng nâng cấp nó; không có thêm an toàn. Có 2 sự lựa chọn với các phần phụ thuộc được chia sẻ: miễn phí cho tất cả, thứ có nguy cơ bị hỏng khi bạn cố gắng chạy nó hoặc trình quản lý gói, có nguy cơ ngăn bạn cài đặt mọi thứ.
jpmc 26

Câu hỏi này không phải là về việc quyết định sử dụng EXE hay DLL nào, mà là về những gì xảy ra sau đó theo mặc định và tại sao. Bạn đang thảo luận về một chủ đề hoàn toàn khác. Khóa được sử dụng sau quyết định EXE hoặc DLL sẽ thực thi để có được một số cấp độ kiểm soát bổ sung bởi người dùng đầu tiên, chính là Windows trong ví dụ này và để cho người khác biết về kiểm soát đó. Và không để "người khác" xóa hoặc ghi vào các tệp mà Windows cần vì một lý do nào đó và do đó khóa chúng, tất nhiên là một cơ chế để phối hợp bổ sung.
Thorsten Schöning

1
Một số EXE hoặc DLL rất có thể không "trong bộ nhớ", nhưng được ánh xạ vào nó theo mặc định. Việc lập bản đồ yêu cầu phải có sẵn nội dung tệp, vì vậy việc thay thế nó một cách tùy tiện được coi là không an toàn theo mặc định và người ta phải biết mình đang làm gì. Rõ ràng là không đúng nếu người ta ngạc nhiên bởi các EXE hoặc DLL bị khóa. OTOH, tất cả các tệp khác chỉ bị khóa theo mặc định, không nhất thiết, vì vậy ứng dụng có thể quyết định xem chúng có cho phép bạn ghi hoặc xóa các thao tác hay không, tùy thuộc vào trường hợp sử dụng của chúng. Các nhà phát triển ứng dụng nên biết rõ hơn những người dùng tùy tiện cách họ sử dụng tệp của họ và hoạt động nào là an toàn khi nào.
Thorsten Schöning

0

Các biến thể NT có

mở tập tin

lệnh này sẽ hiển thị các quy trình có xử lý tệp nào. Tuy nhiên, nó yêu cầu bật cờ toàn cầu hệ thống 'danh sách đối tượng duy trì'

openfiles / local /?

cho bạn biết cách thực hiện điều này và cũng như chịu một khoản phạt về hiệu suất khi làm như vậy.


0

Các tệp thực thi được ánh xạ dần vào bộ nhớ khi chạy. Điều đó có nghĩa là các phần của tệp thực thi được tải khi cần thiết. Nếu tệp bị hoán đổi trước khi tất cả các phần được ánh xạ, nó có thể gây ra sự mất ổn định lớn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.