2010-06-22 16 views
44

Tôi đang viết một daemon Linux. Tôi tìm thấy hai cách để làm điều đó.Linux daemonize

  1. Daemonize quy trình của bạn bằng cách gọi fork() và đặt sid.
  2. Chạy chương trình của bạn với &.

Cách nào phù hợp để thực hiện?

+1

Bạn có thể sử dụng nohup: http://stackoverflow.com/questions/958249/whats-the-difference-between-nohup-and-a-daemon – rogerdpack

Trả lời

76

Từ http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

Dưới đây là các bước để trở thành một daemon:

  1. fork() để phụ huynh có thể thoát ra, này trả về điều khiển dòng lệnh hoặc vỏ cách gọi Chương trình của bạn. Bước này là bắt buộc để quá trình mới được đảm bảo không phải là một nhóm trưởng nhóm. Bước tiếp theo, setsid(), thất bại nếu bạn là một nhóm trưởng nhóm.
  2. setsid() để trở thành một nhóm quá trình và trưởng nhóm phiên. Vì một thiết bị đầu cuối điều khiển được kết hợp với một phiên, và phiên làm việc mới này vẫn chưa có một thiết bị đầu cuối điều khiển, quy trình của chúng tôi hiện nay không có thiết bị đầu cuối điều khiển, đó là một điều tốt cho daemon.
  3. ngã ba() một lần nữa để cha mẹ, (trưởng nhóm phiên), có thể thoát. Điều này có nghĩa rằng chúng ta, với tư cách là một nhà lãnh đạo nhóm không phiên, không bao giờ có thể lấy lại một thiết bị đầu cuối điều khiển.
  4. chdir ("/") để đảm bảo rằng quy trình của chúng tôi không giữ bất kỳ thư mục nào được sử dụng. Việc không thực hiện điều này có thể khiến cho quản trị viên không thể ngắt kết nối hệ thống tệp, vì đó là thư mục hiện tại của chúng tôi. [Tương đương, chúng tôi có thể thay đổi bất kỳ thư mục nào chứa các tệp quan trọng đối với hoạt động của daemon.]
  5. umask (0) để chúng tôi có toàn quyền kiểm soát các quyền của bất kỳ điều gì chúng tôi viết. Chúng ta không biết umask chúng ta có thể thừa kế. [Bước này là tùy chọn]
  6. close() fds 0, 1 và 2. Điều này giải phóng tiêu chuẩn trong, ngoài và lỗi mà chúng tôi đã kế thừa từ quy trình gốc của chúng tôi. Chúng tôi không có cách nào biết được những fds này có thể đã được chuyển hướng đến đâu. Lưu ý rằng nhiều daemon sử dụng sysconf() để xác định giới hạn _SC_OPEN_MAX. _SC_OPEN_MAX cho bạn biết các tệp/quy trình mở tối đa. Sau đó, trong một vòng lặp, daemon có thể đóng tất cả các mô tả tập tin có thể. Bạn phải quyết định xem bạn có cần phải làm điều này hay không. Nếu bạn nghĩ rằng có thể có các bộ mô tả tập tin mở, bạn nên đóng chúng lại, vì có giới hạn về số lượng các mô tả tập tin đồng thời.
  7. Thiết lập mô tả mở mới cho stdin, stdout và stderr. Ngay cả khi bạn không định sử dụng chúng, bạn vẫn nên mở chúng ra.Việc xử lý chính xác những thứ này là vấn đề về hương vị; nếu bạn có một tệp nhật ký, ví dụ, bạn có thể muốn mở nó như là stdout hoặc stderr, và mở '/ dev/null' làm stdin; Ngoài ra, bạn có thể mở '/ dev/console' như stderr và/hoặc stdout và '/ dev/null' làm stdin hoặc bất kỳ kết hợp nào khác có ý nghĩa đối với daemon cụ thể của bạn.

Tốt hơn, chỉ cần gọi hàm daemon() nếu có.

+1

bạn phải đóng tất cả các mô tả mở. Nếu không, các tệp có thể tiếp tục có tham chiếu, ví dụ: các tệp này sẽ không cho phép chúng bị xóa. Điều này khá giống như chdir ("/"). –

+2

@ n-alexanderso - là daemon() đôi dĩa? – Dannyboy

+1

Một ví dụ điển hình về chương trình Ruby WEBrick (chuyển đổi nguồn): http://ruby-doc.org/stdlib-2.1.1/libdoc/webrick/rdoc/WEBrick/Daemon.html –

2

Thực ra để tạo một daemon, bạn phải gấp đôi ngã ba.

Chạy chương trình bằng & làm cho trình chạy chạy chương trình ở chế độ nền, không làm cho trình nền trở thành daemon. Daemons có init (pid 1) là cha mẹ, đó là lý do tại sao cần có hai ngã ba.

Vì vậy, cách tốt nhất để làm việc, nếu chương trình của bạn là một daemon, sẽ tự lo cho vấn đề này (có nhiều phương pháp hơn, xem here). Bạn cũng có thể sử dụng chương trình start-stop-daemon.

5

Đầu tiên. Thứ hai là không daemonizing, nhưng chạy trên nền. Các chương trình được sửa lỗi phải nằm trong nhóm phiên và nhóm xử lý riêng của nó, và nên không có một thiết bị đầu cuối điều khiển.

+1

nhưng tôi vẫn không thể hiểu việc sử dụng phiên thiết lập của riêng là gì và nhóm quá trình – Poorna

2

Bạn đang sử dụng ngôn ngữ nào? Một số ngôn ngữ có các phương thức trợ giúp làm cho việc tạo daemon dễ dàng hơn. Ví dụ, Ruby có gói daemons.

+0

chúng tôi đang sử dụng C++ – Poorna

11

Chỉ cần sử dụng daemon(3) (từ unistd.h).

Các daemon() chức năng là cho các chương trình muốn tách mình khỏi các kiểm soát thiết bị đầu cuối và chạy trong nền như daemon hệ thống. ...

+0

Tôi đã dành một vài ngày điều tra làm thế nào tôi có thể chạy ứng dụng bình như một daemon trên ubuntu sử dụng jenkins cho đến khi tôi nhìn thấy lời khuyên của bạn. Cảm ơn bạn! Sự cố của tôi được giải quyết với lệnh shell 'xuất BUILD_ID = dontKillMe' 'bình daemon chạy' – barbarian

28

Tôi khuyên bạn không nên viết chương trình của mình làm daemon. Làm cho nó chạy trong nền trước với các mô tả tập tin, thư mục hiện tại, nhóm quá trình, vv như được trao cho nó.

Nếu bạn muốn chạy chương trình này dưới dạng daemon, hãy dùng start-stop-daemon (8), init (8), runsv (từ runit), khởi động, systemd, hoặc bất cứ thứ gì để khởi chạy quá trình của bạn dưới dạng daemon . Tức là, hãy để người dùng của bạn quyết định cách chạy chương trình của bạn và không thực thi nó phải chạy như một daemon.

+6

+1. Ít nhất, cung cấp tùy chọn để chạy ở nền trước. –

+0

Xin lỗi để mang lại câu trả lời cũ, nhưng monit có thể khởi động quá trình của bạn như một daemon không? – allaire