דמונים הם תהליכים שאינם פועלים ישירות בשליטת המשתמש אלא משרתים ברקע. בדרך כלל, הם מתחילים באתחול המערכת ופועלים ברציפות עד שהמערכת נכבית. ההבדל היחיד בין תהליכים אלה לתהליכים רגילים הוא שהם אינם שולחים הודעות לקונסולה או למסך בשום אופן.
הנה איך אתה יכול ליצור דמון במחשב לינוקס.
מבוא קצר כיצד נוצרים דמונים
הרבה דמונים פועלים על המערכת וכמה דוגמאות דמונים מוכרות הן כדלקמן:
- כתף: גורם לפקודות לפעול בזמן שצוין
- sshd: מאפשר כניסה למערכת ממכונות מרוחקות
- httpd: משרת דפי אינטרנט
- nfsd: מאפשר שיתוף קבצים ברשת
כמו כן, תהליכי דמון נקראים בדרך כלל כך שהם מסתיימים באות ד, למרות שזה לא חובה.
כדי שתהליך יפעל כדמון, הנתיב הבא מתבצע:
- יש לבצע פעולות ראשוניות, כגון קריאת קובצי תצורה או השגת משאבי מערכת נחוצים, לפני שהתהליך הופך לדמון. כך המערכת יכולה לדווח למשתמש על השגיאות שהתקבלו והתהליך יסתיים עם קוד שגיאה מתאים.
- תהליך ריצה ברקע נוצר עם init כתהליך האב שלו. לשם כך, תת-תהליך מתפצל מתהליך ה-init תחילה, ולאחר מכן התהליך העליון מסתיים ביציאה.
- הפעלה חדשה אמורה להיפתח על ידי קריאה לפונקציה setsid, ויש לנתק את התהליך מהמסוף.
- כל מתארי הקבצים הפתוחים שעברו בירושה מתהליך האב סגורים.
- קלט, פלט סטנדרטי, והודעות שגיאה מופנות אל /dev/null.
- ספריית העבודה של התהליך חייבת להשתנות.
מה זה הפעלות Daemon?
לאחר כניסה למערכת באמצעות מסוף, משתמשים יכולים להריץ יישומים רבים דרך תוכנית המעטפת. תהליכים אלו צריכים להיסגר כאשר המשתמש יוצא מהמערכת. מערכת ההפעלה מקבצת תהליכים אלה לקבוצות הפעלה ותהליכים.
כל מפגש מורכב מקבוצות תהליך. אתה יכול לתאר מצב זה באופן הבא:
המסוף שבו התהליכים מקבלים את התשומות שלהם ושולחים את הפלטים שלהם נקרא מסוף השולט. מסוף שליטה משויך להפעלה אחת בלבד בכל פעם.
לפגישה ולקבוצות התהליך שבו יש מספרי זיהוי (ID); מספרי זיהוי אלו הם מספרי זיהוי התהליך (PID) של ראשי קבוצות המושב והתהליכים. תהליך ילד חולק את אותה קבוצה כמו תהליך האב שלו. כאשר ישנם מספר תהליכים תקשורת עם מנגנון הצינור, התהליך הראשון הופך למנהיג קבוצת התהליך.
יצירת תהליך Daemon בלינוקס
כאן תראה כיצד תוכל ליצור פונקציית דמון. לשם כך, תיצור פונקציה בשם _דימון. אתה יכול להתחיל במתן שם לקוד היישום שיפעל בתור דמון test.c, והקוד שתיצור את פונקציית הדמון בתור daemon.c.
//test.c
#לִכלוֹל <stdio.h>
int_דימון(int, int);
intרָאשִׁי()
{
getchar();
_דימון (0, 0);
getchar();
לַחֲזוֹר0;
}
//daemon.c
#לִכלוֹל <sys/types.h>
#לִכלוֹל <sys/stat.h>
#לִכלוֹל <stdlib.h>
#לִכלוֹל <stdio.h>
#לִכלוֹל <fcntl.h>
#לִכלוֹל <unistd.h>
#לִכלוֹל <linux/fs.h>
#לִכלוֹל <linux/limits.h>
int_דימון(int nochdir, int נוקלוס){
pid_t pid;
pid = fork(); // עזוב את תהליך האב
אם (pid < 0) {
יְצִיאָה(EXIT_FAILURE);
}
אם (pid > 0) {
יְצִיאָה(EXIT_SUCCESS);
}
לַחֲזוֹר0;
}
כדי ליצור דמון, אתה צריך תהליך רקע שתהליך האב שלו מתחיל. בקוד למעלה, _דימון יוצר תהליך ילד ואז הורג את תהליך ההורה. במקרה זה, התהליך החדש שלך יהיה תת-תהליך של init וימשיך לפעול ברקע.
כעת הרכיבו את האפליקציה עם הפקודה הבאה ובחנו את מצב התהליך לפני ואחרי _שד נקרא:
gcc-oמִבְחָןמִבְחָן.cדמון.c
הפעל את האפליקציה ועבור למסוף אחר מבלי ללחוץ על מקשים אחרים:
./מִבְחָן
אתה יכול לראות שהערכים הקשורים לתהליך שלך הם כדלקמן. הנה, תצטרך להשתמש הפקודה ps כדי לקבל מידע הקשור לתהליך. במקרה זה, ה _דימון הפונקציה עדיין לא נקראה.
נ.ב.-ג מִבְחָן -o "pid ppid pgid sid tty סטטפקודה"
# פלט
PID PPID PGID SID TT פקודה STAT
10296 5119 10296 5117 נקודות/2 S+ ./מִבְחָן
כאשר אתה מסתכל על STAT בשדה, אתה רואה שהתהליך שלך פועל אך ממתין להתרחשות אירוע מחוץ ללוח הזמנים שיגרום לו לפעול בחזית.
נוֹטָרִיקוֹן | מַשְׁמָעוּת |
ס | מחכה בשינה לקרות אירוע |
ט | היישום הופסק |
ס | מנהל מושב |
+ | האפליקציה פועלת בחזית |
אתה יכול לראות שתהליך האב של הבקשה שלך הוא המעטפת כצפוי.
ps -jp 5119
# פלט
PID PGID SID TTY TIME CMD
5119 5119 5117 נקודות/2 00:00:02 זש
כעת חזור למסוף שבו אתה מריץ את היישום שלך ולחץ להיכנס להפעיל את _דימון פוּנקצִיָה. לאחר מכן הסתכל שוב על מידע התהליך בטרמינל השני.
נ.ב.-ג מִבְחָן -o "pid ppid pgid sid tty סטטפקודה"
# פלט
PID PPID PGID SID TT פקודה STAT
22504 1 22481 5117 נקודות/2 S ./מִבְחָן
קודם כל, אתה יכול לומר שתהליך המשנה החדש פועל ברקע מכיוון שאתה לא רואה את + דמות ב STAT שדה. כעת בדוק מי הוא תהליך האב של התהליך באמצעות הפקודה הבאה:
ps -jp 1
# פלט
PID PGID SID TTY TIME CMD
1 1 1? 00:00:01systemd
כעת אתה יכול לראות שתהליך האב של התהליך שלך הוא systemd תהליך. הוזכר לעיל שלשלב הבא, הפעלה חדשה אמורה להיפתח ולנתק את התהליך ממסוף הבקרה. לשם כך, אתה משתמש בפונקציית setsid. הוסף את השיחה הזו לשלך _דימון פוּנקצִיָה.
פיסת הקוד שיש להוסיף היא כדלקמן:
if (setsid() == -1)
לַחֲזוֹר-1;
עכשיו אחרי שבדקת את המדינה בעבר _דימון התקשר, כעת תוכל להסיר את הראשון getchar לתפקד ב test.c קוד.
//test.c
#לִכלוֹל <stdio.h>
int_דימון(int, int);
intרָאשִׁי()
{
_דימון (0, 0);
getchar();
לַחֲזוֹר0;
}
לאחר הידור והפעלת האפליקציה שוב, עבור אל הטרמינל שבו עשית את הביקורות שלך. הסטטוס החדש של התהליך שלך הוא כדלקמן:
נ.ב.-ג מִבְחָן -o "pid ppid pgid sid tty סטטפקודה"
# פלט
PID PPID PGID SID TT פקודה STAT
25494 1 25494 25494? Ss ./מִבְחָן
ה ? לחתום על TT השדה מציין שהתהליך שלך אינו מחובר יותר למסוף. שימו לב שה PID, PGID, ו SID הערכים של התהליך שלך זהים. התהליך שלך הוא כעת מוביל מפגשים.
בשלב הבא, שנה את ספריית העבודה לספריית השורש בהתאם לערך הארגומנט שהעברת. אתה יכול להוסיף את הקטע הבא ל- _דימון פונקציה עבור זה:
if (!nochdir) {
אם (chdir("/") == -1)
לַחֲזוֹר-1;
}
כעת, לפי הטיעון שהועבר, ניתן לסגור את כל מתארי הקבצים. הוסף את הקוד הבא ל- _דימון פוּנקצִיָה:
#define NR_OPEN 1024
if (!noclose) {
עבור (i = 0; אני < NR_OPEN; i++)
סגור (i);
לִפְתוֹחַ("/dev/ריק", O_RDWR);
dup (0);
dup (0);
}
לאחר סגירת כל מתארי הקבצים, קבצים חדשים שנפתחו על ידי דמון יוצגו עם המתארים 0, 1 ו-2 בהתאמה. במקרה זה, למשל, ה printf הפקודות בקוד יופנו לקובץ השני שנפתח. כדי להימנע מכך, שלושת המזהים הראשונים מצביעים על /dev/null התקן.
במקרה זה, המצב הסופי של _דימון הפונקציה תהיה כדלקמן:
#לִכלוֹל <sys/types.h>
#לִכלוֹל <sys/stat.h>
#לִכלוֹל <stdio.h>
#לִכלוֹל <stdlib.h>
#לִכלוֹל <fcntl.h>
#לִכלוֹל <errno.h>
#לִכלוֹל <unistd.h>
#לִכלוֹל <syslog.h>
#לִכלוֹל <מחרוזת.ח>
int_דימון(בָּטֵל){
// PID: מזהה תהליך
// SID: מזהה הפעלה
pid_t pid, סיד;
pid = fork(); // עזוב את תהליך האב
אם (pid < 0) {
יְצִיאָה(EXIT_FAILURE);
}
אם (pid > 0) {
יְצִיאָה(EXIT_SUCCESS);
}
// לִיצוֹר א SIDליֶלֶד
sid = setsid();
אם (סיד < 0) {
// נכשל
יְצִיאָה(EXIT_FAILURE);
}
אם ((chdir("/")) < 0) {
// נכשל
יְצִיאָה(EXIT_FAILURE);
}
סגור (STDIN_FILENO);
סגור (STDOUT_FILENO);
סגור (STDERR_FILENO);
בזמן (1) {
// כמה משימות
שינה (30);
}
יְצִיאָה(EXIT_SUCCESS);
}
להלן דוגמה לקטע קוד המריץ את sshd יישום בתור א דמון:
...
if (!(debug_flag || inetd_flag || no_daemon_flag)) {
int fd;
if (דימון (0, 0) < 0)
קָטלָנִי("daemon() נכשל: %.200s", strerror (errno));
/* נתק מה-tty השולט. */
fd = פתוח (_PATH_TTY, O_RDWR | O_NOCTTY);
אם (fd >= 0) {
(בָּטֵל) ioctl (fd, TIOCNOTTY, NULL);
סגור (fd);
}
}
...
דמונים חשובים עבור תכנות מערכות לינוקס
דמונים הם תוכנות המבצעות פעולות שונות בצורה מוגדרת מראש המוגדרת בתגובה לאירועים מסוימים. הם פועלים בשקט במחשב הלינוקס שלך. הם לא נמצאים בשליטה ישירה של המשתמש ולכל שירות שפועל ברקע יש את הדמון שלו.
חשוב לשלוט בדמונים כדי ללמוד את מבנה הליבה של מערכת ההפעלה לינוקס ולהבין את פעולתן של ארכיטקטורות מערכת שונות.
מה זה דימון?
קרא הבא
נושאים קשורים
- לינוקס
- ליבת לינוקס
- תִכנוּת
- C תכנות
על הסופר

מהנדס ומפתח תוכנה חובב מתמטיקה וטכנולוגיה. הוא תמיד אהב מחשבים, מתמטיקה ופיזיקה. הוא פיתח פרויקטים של מנוע משחקים וכן למידת מכונה, רשתות עצביות מלאכותיות וספריות אלגברה ליניארית. יתר על כן ממשיך לעבוד על למידת מכונה ומטריצות ליניאריות.
הירשם לניוזלטר שלנו
הצטרף לניוזלטר שלנו לקבלת טיפים טכניים, ביקורות, ספרים אלקטרוניים בחינם ומבצעים בלעדיים!
לחץ כאן כדי להירשם