Về daemon process trong linux
Linux
77
System
17
White

LinhPT viết ngày 28/02/2017

Tiếp tục là note cá nhân của mình trong quá trình đọc Advanced Programming in the Unix environment. Lần này sẽ là về Daemon process.

Về daemon process

Daemon process là các tiến trình mà sẽ sống dai dẳng, hay nói đơn giản hơn là không chết sau khi làm một task nào đó mà sẽ đợi để làm một cái gì đó tiếp theo. Cacd daemon process thường gặp như là web server hay là database..

Đặc điểm của daemon process

Chúng ta có thể sử dụng câu lệnh ps

ps -axj

Ouput sẽ đại loại như sau

UID       PID  PPID  PGID   SID TTY CMD
root        1     0     1     1 ?   /sbin/init
root        2     0     0     0 ?   [kthreadd]
root        3     2     0     0 ?   [ksoftirqd/0]
root        6     2     0     0 ?   [migration/0]
root        7     2     0     0 ?   [watchdog/0]
root       21     2     0     0 ?   [cpuset]
root       22     2     0     0 ?   [khelper]
root       26     2     0     0 ?   [sync_supers]
root       27     2     0     0 ?   [bdi-default]
root       29     2     0     0 ?   [kblockd]
root       35     2     0     0 ?   [kswapd0]
root       49     2     0     0 ?   [scsi_eh_0]
root      256     2     0     0 ?   [jbd2/sda5-8]
root      257     2     0     0 ?   [ext4-dio-unwrit]
syslog    847     1   843   843 ?   rsyslogd -c5
root      906     1   906   906 ?   /usr/sbin/cupsd -F
root     1037     1  1037  1037 ?   /usr/sbin/inetd
root     1067     1  1067  1067 ?   cron

Các process có dấu ngoặc là của kernel.

Coding rule

Để tự viết một daemon process thì có một số luật mà bạn cần phải nhớ:

  • Gọi hàm umask để set file mode creation cho một giá trị đã biết, thường là 0. Việc này để tránh việc process con kế thừa lại file mode từ process cha dẫn đến các hành vi không mong muốn.
  • Gọi fork và để cho process cha exit(). Việc này sẽ tạo ra một vài hiệu quả: đầu tiên là process cha exit() sẽ làm cho shell nghĩ là process đã kết thúc. Ngoài ra process con sẽ kế thừa group id từ process cha và có process id tách biệt, do đó chúng ta có thể đảm bảo là process con không phải là group leader, mà việc này sẽ là điều kiện tiên quyết cho việc gọi setsid ở dưới đây.
  • Gọi setsidđể tạo session mới. Ở một số hệ thống sử dụng System V, chúng ta hay được recommend sử dụng kĩ thuật double fork. Việc này để đảm bảo process con không phải là session leader, tránh được việc nó sẽ dành quyền kiểm soát controlling terminal.
  • Chuyển directory hiện tại sang root directory. Việc này nhằm tránh khi process con chạy trong thư mục được mount, khiến cho thư mục này không thể bị unmount.
  • Đóng file descriptor ngay khi có thể
  • Một vài daemon mở file descriptor 0,1,2 vào /dev/null.

Dưới đây là một ví dụ về code dùng để daemonize

#include "apue.h"
#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>

void
daemonize(const char *cmd)
{
    int                 i, fd0, fd1, fd2;
    pid_t               pid;
    struct rlimit       rl;
    struct sigaction    sa;

    /*
     * Clear file creation mask.
     */
    umask(0);

    /*
     * Get maximum number of file descriptors.
     */
    if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
        err_quit("%s: can′t get file limit", cmd);

    /*
     * Become a session leader to lose controlling TTY.
     */
    if ((pid = fork()) < 0)
        err_quit("%s: can′t fork", cmd);
    else if (pid != 0) /* parent */
        exit(0);
    setsid();

    /*
     * Ensure future opens won′t allocate controlling TTYs.
     */
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGHUP, &sa, NULL) < 0)
        err_quit("%s: can′t ignore SIGHUP", cmd);
    if ((pid = fork()) < 0)
        err_quit("%s: can′t fork", cmd);
    else if (pid != 0) /* parent */
        exit(0);

    /*
     * Change the current working directory to the root so
     * we won′t prevent file systems from being unmounted.
     */
    if (chdir("/") < 0)
        err_quit("%s: can′t change directory to /", cmd);

    /*
     * Close all open file descriptors.
     */
    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for (i = 0; i < rl.rlim_max; i++)
        close(i);

    /*
     * Attach file descriptors 0, 1, and 2 to /dev/null.
     */
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);

    /*
     * Initialize the log file.
     */
    openlog(cmd, LOG_CONS, LOG_DAEMON);
    if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d",
          fd0, fd1, fd2);
        exit(1);
    }
}
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

LinhPT

20 bài viết.
57 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
33 3
Mình thi thoảng phải quản lý linux server, mà trong đó có một số thao tác quản lý quan trong như quản lý đĩa cứng, quản lý mạng, quản lý đường truy...
LinhPT viết hơn 2 năm trước
33 3
White
23 2
(Ảnh) Tiêu đề chỉ là câu khách :v, thực ra là có một vài điểm về mysql explain mà chắc chưa nhiều bạn biết, tớ cũng hay quên nên note lại cho nhớ ...
LinhPT viết hơn 2 năm trước
23 2
White
18 0
Bài viết được dịch từ http://qiita.com/sion_cojp/items/04a2aa76a1021fe77079 Điều cần nhớ trước khi đánh bất kì câu lệnh nào ①Để tránh làm nặng...
LinhPT viết 9 tháng trước
18 0
Bài viết liên quan
White
1 0
sudo du sh
t viết gần 2 năm trước
1 0
White
7 3
Đã có rất nhiều bài viết về process trên linux trên kipalog https://kipalog.com/posts/HedieuhanhProcess https://kipalog.com/posts/GioithieuveUN...
LinhPT viết 12 tháng trước
7 3
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
20 bài viết.
57 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!