שאלה על processes בלינוקס

nocgod

New member
שאלה על processes בלינוקס

יש דרך לדעת בזמן ריצת קוד (בdebug) איזה פרוססים רצים ואיזה פייפים פתוחים בין איזה פרוססים?
ציירתי לעצמי על דף מה אני חושב שנפתח, משום מה הeclipse באמצעות GDB לא בדיוק מנדב מידע על process אלא רק על threads....
 

nocgod

New member
אני מתכוון כמובן חוץ מ

ps -aux | grep proc_name
משהו בתוך סביבת העבודה...
 

nocgod

New member
הסתדרתי בנושא הזה

מסתבר שאם יש לך GDB מעל 7.2 אז אם מפעילים אופציה של non-stop debugging הוא עושה אוטומטית attach לprocesses שעושים להם fork.
סתם שתדעו
 

nocgod

New member
זה נחמד

זה עדיין לא מראה לי את הpipes אבל חצי דרך עשינו...
 

nocgod

New member
שאלה נוספת

בהנחה שאני רוצה להשתמש ב 2 pipes כדי לייצר תקשורת דו כיוונית בין 2 תהליכים

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

int main()
{
pid_t childId;
int fatherReadPipe[2];
int sonReadPipe[2];

char buf[PIPE_BUF];

pipe(fatherReadPipe);
pipe(sonReadPipe);

childId = fork();

switch (childId)
{
case -1:
{
printf("Error at fork\n");
exit(-1);
break;
}
case 0:
{
close(fatherReadPipe[0]);
printf("im process #%d, enter a message to send to father\n", getpid());
gets(buf);
write(fatherReadPipe[1], buf, strlen(buf) + 1);
read(sonReadPipe[0], buf, PIPE_BUF);
printf("father said:\n");
printf("%s\n", buf);
break;
}
default:
{
close(sonReadPipe[0]);
read(fatherReadPipe[0],buf,PIPE_BUF);
printf("im process #%d, this is a message my son sent me\n%s\n", getpid(),buf);
printf("enter a message to send to son\n");
gets(buf);
write(sonReadPipe[1],buf,strlen(buf) + 1);
break;
}
}


return 0;
}


האם קיימת דרך יותר יפה לעשות את זה? כלומר לא לעשות 2 מערכים ולהעביר את שתיהם ל pipe ואז לחסום צד אצל אבא צד אצל הבן?
 

nocgod

New member
על פנוי נראה שהכל יפה...

אבל בתחלס אני משתמש ב 2 פייפים half duplex כדי לייצר pipe אחד full duplex אבל בתהליך הזה אני מבזבז 2 int...בשביל צינור אחד
 

nocgod

New member
אני עושה עבודה

ובה אני עושה סימולציה לshell
לפי דרישות העבודה כל folder ב FS ייוצג על ידי Process...ככה שכמות הintegerים המיותרים גודלת בקצב מסחרר...
חשבתי יש דרך יותר יפה לבצע את העבודה...
 

selalerer

New member
לכל process מוקצה heap ו-stack הרבה יותר...

...גדולים מכל ה-intים שתשתמש. אתה מחפש לחסוך במקום הלא נכון.

אל תניח מראש מה יעשה לך בעיות. צריך להימנע מבעיות מראש אבל זה דורש הרבה נסיון לדעת בדיוק מהן בכל משימה ומשימה.

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

BravoMan

Active member
לא כ"כ מסחרר:

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

אני לא רואה משהו שהייתי משנה בקוד שכתבת (אם כי אני חייב לציין שנושא ה-pipe קצת חלוד עצלי), אבל אם להיות ממש פדנטים, אולי שווה ליצור איזה define בנוסח:

#define READ_END 0
#define WRITE_END 1


רק כדי להימנע מה-"magic numbers".
 

nocgod

New member
ואו רעיון אדיר

זה הדברים הקטנים שעושים לי את ההבדל בכתיבה!
תודה על הטיפ!!!

עכשיו אני משלם על זה שאני כותב המון קוד מבלי לבדוק אותו בחתיכות...בחיים שלי לא חשבתי שלעשות debug בתוכנה רב-תהליכית יהיה כזה סיוט....
 

nocgod

New member
אשמח אם מישהו יוכל להסביר לי למה זה לא עובד

הרעיון
process אחד שולח לשני test
השני עונה roger roger
כל סיפור האהבה הזה מוצג על המסך


אני מנסה כל היום לסדר את המערכת הזאת של לשלוח אחד לשני הודעות באמצעות ה pipes ואני מרגיש שאני מפספס משהו...

נ"ב
זה ירוץ רק בלינוקס...
 

selalerer

New member
כמה דברים:

1. "לא עובד" לא אומר לנו כלום. ספר מה כן קורה.
2. אתה לא בודק אם שום דבר הצליח או נכשל. לכל system call כזה שאתה משתמש יש ערך מוחזר. בדוק אותו. אם הוא לא ערך תקין, תדפיס את הבעיה.
 

nocgod

New member
אם היה קורה משהו הייתי אומר...

אבל זהו, זה העניין... הכל עובר ופשוט לא מודפס כלום, ואין שגיאות ואין כלום
אני חושב שזה קורה כי אני צריך איכשהו להצליב את הpipes אחרי שאני עושה את הfork יותר מזה, הצלחתי לקבל הדפסה של test על המסך אחרי שהרצתי את הפקודה
void initPipe(Pipe* p)
{
p->readPipe[READ_END] = p->writePipe[READ_END];
}

בprocess אב
insertFolder(&curFolder->folderList, getFolderHandle(childId, con, name));
initPipe(con);
sendMsg(curFolder->folderList->folder, "test");
readMsg(curFolder->folderList->folder, msg);
printf("%s\n", msg);
break;

אני חושב שאני מפספס פה משהו קטן בעל משמעות גדולה...
 

BravoMan

Active member
לא קראתי את כל הקוד, אבל אני חושב שמצאתי

בעיה בלוגיקה של התוכנית שלך:

בפונקציה makeDir, ב-case של תהליך "בן" אתה מנסה לאתחל שוב את הפרמטר curFolder עם הפונקציה initFolder ולמעשה דורס את המידע של הספרייה שאמורה להיות ספריית אב.
 

nocgod

New member
פה אתה טיפה טועה

נכון אני דורס את המידע שהיה במבנה אליו מצביע curFolder
אבל... מאחר והdata segment מועתק כולו גם לבן, והcurFolder כבר אינו מייצג את האבא אלא מייצג את הבן, אני דורס את המידע במבנה (שים לה שהhandler שהבן מקבל מכיל את הID של האבא)
הבעיה שלי היא שאני לא מצליחח להתחבר לתהליך בן כדי לעשות לו debug ככה שכל הדיבאג שלי מעצם מסתכם ממה שאני יכול להסיק מהאבא
בגלל זה גם התחלתי את העבודה מחדש והחלטתי קודם לבנות את המנגנון תקשורת בין תהליכים ורק את לבנות את ה shell
 

BravoMan

Active member
אתה צודק...

בכל אופן, קח עוד טיפ קטן שיהיה אולי שימושי:
התרגלתי לעשות את זה כי אני עובד עם לא מעט מכשירים שלא ניתן להתחבר עליהם עם debugger בשום צורה.


{ /* DEBUG BLOCK */
FILE *f = fopen("debug.txt", ab);
if (f != NULL) {
fprintf(f, "Some debug info\n");
fclose(f);
}
}


פשוט תוקעים בלוק אנונימי כזה בכל מקום לצריך להוציא מידע.
זה מבודד את קוד ה-debug והופך אותו לעצמאי לחלוטין וההערה בתחילת הבלוק (שיכול להיות גם יותר ייחודית) עוזרת למצוא ולנקות אותם אחר כך.
 

nocgod

New member
רעיון מעולה...

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

ברגע שסיימתי להתעסק עם הIPC ועשיתי לעצמי מעין פרוטוקול תקשורת בין תהליכים, העבודה הולכת פחות או יותר חלק :)
תודה...עזרת לי מאוד...
 
למעלה