2011-02-01 58 views
0

我已經在C中實現了一個基本鏈接列表,作爲項目的一部分來開發一個簡單的shell - 它支持通過維護shell在其中運行的pid列表來支持進程的後臺背景。代碼如下。使用queue_process(some_pid)插入時第一次正常工作,但隨後鏈接列表的行爲就好像列表中沒有任何節點(即「無現有進程」總是由調試功能打印)。我已經檢查過這個文件和調用這些函數的文件,以便將頭指針重置爲無效。我在鏈接列表邏輯中遺漏了什麼?C中丟失頭信息的鏈接列表

到queue_process編輯電話:發生在由shell啓動的子進程,看起來像這樣/編輯:queue_process(getpid())

謝謝!

void queue_process(pid_t pid_to_insert) 
{ 
    pmesg(2, "In queue_process.\n"); 
    if (head == NULL) 
    { 
     pmesg(3, "No existing processes.\n"); 
     head = malloc(sizeof(struct xssh_process)); 
     head->pid = pid_to_insert; 
     head->next = NULL; 
    } 
    else 
    { 
     pmesg(3, "There are existing processes.\n"); 
     struct xssh_process *new_process = malloc(sizeof(struct xssh_process)); 
     new_process->next= head; 
     head = new_process; 
    } 
    print_processes(); 
} 

void print_processes() 
{ 
    pmesg(2, "In print_processes.\n"); 
    struct xssh_process *at_node = head; 
    if (head == NULL) { pmesg(2, "There are currently no background processes.\n"); return; } 
    pmesg(2, "Process IDs from head (most recently executed) to tail: %i -> ", at_node->pid); 
    while (at_node != NULL) 
    { 
     pmesg(2, "%i ->", at_node->pid); 
     at_node = at_node->next; 
    } 
    pmesg(3, "Head's pid in print is %i.\n", head->pid); 
} 
+0

查找鏈表的不同實現會更好嗎?這個代碼或者總體程序似乎有某種固有的缺陷。 – 2011-02-01 06:20:53

+0

什麼是「struct xssh_process」的聲明?它是一個完整的結構或只是一個標籤?在編寫鏈表時,您可能首先使用了一個不完整的struct標籤,以使節點能夠指向自己。 – Lundin 2011-02-01 14:40:09

回答

1

根據提供的額外信息:

到queue_process的呼叫 發生由外殼 啓動子進程,看起來像這樣: queue_process(getpid())

您嘗試添加到子進程中的鏈接列表(由fork()創建),然後檢查父級中的鏈接列表。

這將不起作用 - fork()創建一個完整的,獨立的副本的過程。除了明確標記爲共享的內存之外,對每個進程私有的fork()之後所做的變量修改。父母不會看到孩子所做的修改,孩子也不會看到父母所做的修改。

您應該有父呼叫queue_process(child_pid),其中child_pid是返回值fork()

3

這是一個與你所遇到的bug沒有幫助,但你的代碼給我的印象過於複雜:

pmesg(2, "In queue_process.\n"); 
if (head == NULL) 
{ 
    pmesg(3, "No existing processes.\n"); 
    head = malloc(sizeof(struct xssh_process)); 
    head->pid = pid_to_insert; 
    head->next = NULL; 
    tail = malloc(sizeof(struct xssh_process)); 
    tail = head; 
} 
else 
{ 
    pmesg(3, "There are existing processes.\n"); 
    struct xssh_process *new_process = malloc(sizeof(struct xssh_process)); 
    new_process->next= head; 
    head = new_process; 
} 

這可以簡化不少。既然你在列表的頭部插入無論如何,你不需要單獨的邏輯空單:

void print_processes() { 
    struct xssh_process *p; 
    for (p=head; p!=NULL; p=p->next) 
     printf("%d\n", p->pid); 
} 

OTOH:

void queue_process(pid_t pid_to_insert) { 
    struct xssh_process *new_process = malloc(sizeof(*new_process)); 
    new_process->pid = pid_to_insert; 
    new_process->next = head; 
    head = new_process; 
} 

同樣,print_processes可以有點被下調,鏈表會讓我覺得這是一個糟糕的選擇 - 考慮到指針至少和PID一樣大,至少有50%的內存是指針的開銷。

+0

謝謝;這絕對是更簡潔的代碼。 – 2011-02-01 05:55:59

0

試試這個:

void queue_process(pid_t pid_to_insert) 
{ 
    pmesg(2, "In queue_process.\n"); 
    if (head == NULL) 
    { 
     pmesg(3, "No existing processes.\n"); 
     head = malloc(sizeof(struct xssh_process)); 
     head->pid = pid_to_insert; 
     head->next = NULL; 
     // This malloc is not required 
     // tail = malloc(sizeof(struct xssh_process)); 
     tail = head; 
    } 
    else 
    { 
     pmesg(3, "There are existing processes.\n"); 
     struct xssh_process *new_process = malloc(sizeof(struct xssh_process)); 
     new_process->next= head; 
     head = new_process; 
    } 
    print_processes(); 
} 

void print_processes() 
{ 
    pmesg(2, "In print_processes.\n"); 
    if (head == NULL) { pmesg(2, "There are currently no background processes.\n"); return; } 
    struct xssh_process *at_node = head; 

    // While at_node != null 
    do 
    { 
     pmesg(2, "%i ->", at_node->pid); 
     at_node = at_node->next; 
    } 
    while (at_node != null); 
    pmesg(3, "Head's pid in print is %i.\n", head->pid); 
} 
+0

不幸的是,仍然有同樣的問題。 – 2011-02-01 06:19:42

+0

每當你調用你的函數,它是否打印進入隊列或第一個進程的最後一個進程?它打印剩餘的進程嗎?我問這個問題的原因是,解決方案取決於「頭」和「尾」指針的聲明。 – vamyip 2011-02-01 06:31:23

1

當一個變量的值神祕變化,它往往是因爲你寫超越另一個變量,恰好是在內存中相鄰的邊界。

嘗試在head的調試器中設置一個觀察點,只要該變量發生變化,該觀察點就會進入調試器。這應該讓你很快跟蹤這個問題。在gdb中,該命令將是watch head