gpt4 book ai didi

c - 从c中的列表中读取函数中的结构

转载 作者:行者123 更新时间:2023-11-30 19:46:18 25 4
gpt4 key购买 nike

我正在列表中写入一些结构信息。该结构体是Pstatus,它是全局定义的pGlobal。现在我想在函数 getStatus() 中使用 pGlobal 读取此列表,但这不起作用。所以我创建了另一个定义 pGlobal2 但这会带来很多问题。我想读出我的 list ,但我得到了一些虚假信息。在此列表中,存储了正在运行的进程的 pid,但是当我读出它时,我只得到最后的 pid 和信息,但我得到的信息与存储的 pid 一样多。如果此列表中存储了 5 个 pid,则我会获取最后一个 5 次。我想那是因为我有 pGlobal 和 pGlobal2。有人可以帮助我吗?

    #include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>


#include "utils.h"
#include "listen.h"
#include "wortspeicher.h"
#include "kommandos.h"
#include "frontend.h"
#include "parser.h"
#include "variablen.h"

int interpretiere(Kommando k, int forkexec);
int interpretiere_einfach(Kommando k, int forkexec);
int getStatus();
Pstatus pGlobal;
Pstatus *pGlobal2;

Liste procTable;


int aufruf(Kommando k, int forkexec){

int kind_status, i;

/* Programmaufruf im aktuellen Prozess (forkexec==0)
oder Subprozess (forkexec==1)
*/

if(forkexec){
int pid=fork();

switch (pid){
case -1:
perror("Fehler bei fork");
return(-1);
case 0:
if(umlenkungen(k))
exit(1);
do_execvp(k->u.einfach.wortanzahl, k->u.einfach.worte);
abbruch("interner Fehler 001"); /* sollte nie ausgeführt werden */
default:
if(k->endeabwarten) {
/* So einfach geht das hier nicht! */

/* schreibt die PID, den Namen und den Status in die Tabelle */
pGlobal = erzeugeProzess (pid, k->u.einfach.worte[0], "RUNNING"); /*k->u.einfach.worte[0] */
/* Debug: print
printf("\npid: %d\tstatus: %s\n", p.pid, p.status);
*/
i = listeLaenge(procTable);
procTable = listeAnfuegen(procTable, &pGlobal);
if(listeLaenge(procTable) <= i) {
fprintf(stderr, "Fehler beim Schreiben in die Liste!");
}

/* Debug printf: Bis hierhin wird alles ordentlich in die Liste geschrieben! */
/*test = listeKopf(procTable);
printf("pointer1: %p",test);
printf("\npid: %d\tstatus: %s\n", test->pid, test->status); */


waitpid(pid, &kind_status, 0);
if(WIFEXITED(kind_status)){
printf("Kind mit der PID %d wurde beendet\n",pid);
if (WEXITSTATUS(kind_status) == 0) {
/** setze status exit(0) */
printf("Kind erfolgreich\n");
pGlobal = statusAendern(pGlobal,pid,"exit(0)");
}
/* nicht erfolgreiche ausgeführt */
else
{
/** setze status exit(1) */
printf("Kind nicht erfolgreich\n");
pGlobal = statusAendern(pGlobal,pid,"exit(1)");
}
}
else if(WIFSIGNALED(kind_status)){
printf("Kind mit der PID %d wurde durch Signal abgebrochen. Signalnummer: %d\n",pid, WTERMSIG(kind_status));
pGlobal = statusAendern(pGlobal,pid,"signal");
}
}
else {
fprintf(stderr, "Programm nicht beendet\n");
fprintf(stdout, "PID: %i\n", pid);
}
return 0;
}
}

/* nur exec, kein fork */
if(umlenkungen(k))
exit(1);
do_execvp(k->u.einfach.wortanzahl, k->u.einfach.worte);
abbruch("interner Fehler 001"); /* sollte nie ausgeführt werden */
exit(1);
}


int interpretiere_einfach(Kommando k, int forkexec){

char **worte = k->u.einfach.worte;
int anzahl=k->u.einfach.wortanzahl;

/* gibt den Status der Subprozesse zurück */
if (strcmp(worte[0], "status")==0){

/* NYI */
getStatus();

}

return aufruf(k, forkexec);
}

int getStatus() {

Liste temp, temp2;

fprintf(stdout, "---------------------\n----Statustabelle----\n---------------------\n");

temp = procTable;

printf("laenge der liste: %d\n",listeLaenge(temp));

/*fprintf(stdout, "Pid: %d", p->pid);*/

if(listeLaenge(temp) < 1) {
fprintf(stdout, "Liste ist leer.\n");
return 0;
}

while(temp != NULL){

pGlobal2 = listeKopf(temp);

/*printf("check: %d\n",pGlobal2->check);*/

if(pGlobal2->check < 1) {
fprintf(stdout,"PID: %d, Programm: %s, Status: %s\n",pGlobal2->pid, pGlobal2->name, pGlobal2->status);
}

if(strcmp(pGlobal2->status, "RUNNING") != 0) {
pGlobal2->check = 1;
}

/*if(strcmp(pGlobal2->status, "RUNNING") == 0) {
printf("eintrag behalten");
listeAnfuegen(temp2, pGlobal2);
}*/


/* wenn status != running -> p.checked() */

temp = listeRest(temp);
}
return 0;
}

}

我已经得到了结构

typedef struct {
int pid; /* Prozess ID */
char* name; /* Prozess Name (Programm) */
char* status; /* Status des Programms */
int check; /* bereits abgerufen? 1 - abgerufen, 0 - nicht abgerufen */
} Pstatus;

听:

typedef struct liste {
void *kopf;
struct liste *rest;
} *Liste;

列表科普夫:

void* listeKopf(Liste l) { 
if(l==NULL)
abbruch("listeKopf(listeLeer) undefiniert");
return l->kopf;
}

listeAnfuegen:

Liste listeAnfuegen(Liste l, void* element){
Liste neu=reserviere(sizeof (struct liste));
neu->kopf = element;
neu->rest = l;
return neu;
}

最佳答案

您提供了大量信息,但没有提供关键内容。因此,我假设 erzeugeProzess 返回一个结构 Pstatus。您可以像这样将节点添加到列表中:

pGlobal = erzeugeProzess(pid, k->u.einfach.worte[0], "RUNNING");
procTable = listeAnfuegen(procTable, &pGlobal);

因此,您始终将 pGlobal 的地址添加到您的列表中,当然,该列表始终包含上次调用 erzeugeProzess 时分配的内容。 (这也是您的代码无法使用局部变量的原因:列表中的引用是堆栈上的某个位置,该位置很可能不包含有用的信息。)

解决方案是让erzeugeProzess真正在堆栈上创建一个对象,例如:

Pstatus *proc_new(...)
{
Pstatus *proc = malloc(sizeof(*proc));

// initialise
return proc;
}

这将创建一个新进程,并在堆上拥有自己的数据,您可以将其分配给列表。不过,您需要在某个时候释放进程。

完成此操作后,您将不再需要全局变量。使用局部变量。您不会丢失引用,因为您将其存储在列表中:

Pstatus *p = proc_new(pid, k->u.einfach.worte[0], "RUNNING");
procTable = listeAnfuegen(procTable, p);

附带说明:您的代码有一些非常尴尬的命名约定。例如,erzeugeProzess 表示createProces,但在您的版本中,它不会创建任何内容。 (通常假设 create 或其名称包含 new 的函数在堆上创建内容。)

同样,您所说的列表的 kopfhead 并不是它的头部。它是与列表中一个节点关联的数据。头部将是它的第一个元素。

关于c - 从c中的列表中读取函数中的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24202205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com