如何解决通过管道和叉子传递具有2个动态数组的struct
| 我有大学功课。我的作业是使用fork并使用流水线方法通过子进程和父进程传递数据来进行项目。好吧,我们需要创建两个管道。第一个管道发送一个txt文件,您将在其中写入\“ Ps -A \”的结果,第二个管道将返回pid及其优先级。教授说我们应该使用动态数组,并通过一个结构将pids数组和ppids数组传递回child.Child在屏幕上打印这两个数组。我的问题是孩子在这里填充了所有好的数组,但是当我将它们发送给父亲时,父亲不会简单地从struct中读取数组,也不会在屏幕上打印任何内容:(您能帮我这个忙吗? struct dyna {
int *pids;
int *ppids;
};
int main(int argc,char *argv[]){
int child_id;
int pipe_pc[2],pipe_cp[2];
int result_pc,result_cp;
int lines1,i;
if (argc!=2)//elegxos gia to an ta arguments pou edwse o xristis einai arxeio1 arxeio2 {
fprintf(stderr,\"Lathos arithmos orismaton.To swsto einai %s filename.txtn\",argv[0]);
exit(1);
} else {
result_pc=pipe(pipe_pc);
if (result_pc==-1) exit(-1);
result_cp=pipe(pipe_cp);
if (result_cp==-1) exit(-1);
struct dyna dyn;
child_id=fork();
if (child_id==-1) exit(-1);
//child
if (child_id==0){
char child_read_msg[buff];
close(pipe_pc[1]);
memset(child_read_msg,buff);
read(pipe_pc[0],child_read_msg,buff);
printf(\"nchild process:child read from father: %sn\",child_read_msg);
char child_write_msg[buff]=\"lol\",lines[buff]=\"lines.txt\",* pch,**grammes;
FILE *pFile1,*pFile2;
long lSize1,lSize2;
char *buffer1,*command,*buffer2;
size_t file1str,file2str;
command = (char*)malloc(strlen(\"wc -l >\")+strlen(child_read_msg)+strlen(lines));
sprintf(command,\"ps -A> %s\",child_read_msg);
system(command);
//vazoume ta periexomena tou processes.txt se enan buffer
pFile1 = fopen ( child_read_msg,\"rb\" );
fseek (pFile1,SEEK_END);
lSize1 = ftell (pFile1);
rewind (pFile1);
buffer1 = (char*) malloc (sizeof(char)*lSize1);
if (buffer1 == NULL) {fputs (\"Memory error\",stderr); }
file1str = fread (buffer1,1,lSize1,pFile1);
if (file1str != lSize1) {fputs (\"Reading error\",stderr); }
fclose(pFile1);
//vriskoume ton arithmon grammon tou arxeIoU
sprintf(command,\"wc -l %s>%s\",lines);
system(command);
pFile2 = fopen ( lines,\"rb\" );
fseek (pFile2,SEEK_END);
lSize2 = ftell (pFile2);
rewind (pFile2);
buffer2 = (char*) malloc (sizeof(char)*lSize1);
if (buffer2 == NULL) {fputs (\"Memory error\",stderr); }
file2str = fread (buffer2,lSize2,pFile2);
if (file2str != lSize2) {fputs (\"Reading error\",stderr); }
fclose(pFile2);
sscanf(buffer2,\"%d\",&lines1); //lines1= arithmos grammon tou processes.txt
sprintf(command,\"rm -r %s\",lines);
system(command);
free(buffer2);
i=0;
dyn.pids=(int *)calloc(sizeof(int),lines1); //desmeuei mnimi dinamika gia ton proto pinaka tis struct pou periexei ta pid
pch = strtok (buffer1,\"n\");
while (pch != NULL){
sscanf(pch,&dyn.pids[i]);
pch = strtok (NULL,\"n\");
i++;
}
dyn.ppids=(int *)calloc(sizeof(int),lines1);
for (i=1;i<lines1;i++) /*Gemizei ton pinaka kai vazei tis proteraiotites tis kathe diergasias */ {
dyn.ppids[i]=getpriority(PRIO_PROCESS,dyn.pids[i]);
}
//for (i=1;i<lines1;i++){
//printf(\"%dn\",dyn.ppids[i]);
//}
close(pipe_cp[0]);
write(pipe_cp[1],&dyn,sizeof(dyn));
}
//parent
else {
close(pipe_pc[0]);
write(pipe_pc[1],argv[1],strlen(argv[1]));
printf(\"nparent process: father wrote to child: %sn\",argv[1]);
wait(NULL);
close(pipe_cp[1]);//kleinoume to write-end,o pateras mono diabazei apo to pipe_cp
read(pipe_cp[0],sizeof(dyn));//parent diabazei ayto poy exei grapsei to paidi
//prints the array with the priorities of the processes
for (i=1;i<lines1;i++){
printf(\"%dn\",dyn.ppids[i]);
}
}
return 0;
}
}
解决方法
write(pipe_cp[1],&dyn,sizeof(dyn))
只是从您的结构中传输两个指针,而不是它们所引用的实际数据。这些指针持有的地址在父进程中将毫无意义,因为它具有单独的地址空间。在此处取消引用将导致不确定的行为,很可能是分段错误。
如果您希望代码以这种方式工作,则需要将结构的成员声明为固定大小的数组,而不是指针。通过这样做,该结构实质上成为了一个容器,它本身包含两个数组。
,有一个很好的用于序列化C结构和数组的库tpl。我已经使用了一段时间了,对此我感到非常满意。
您可能想看看它,看看他们是如何做到的。
网站上使用文件的示例(不限于文件,应适用于任何可以传递消息的操作):
/* Storing ids and usernames */
#include <tpl.h>
int main(int argc,char *argv[]) {
tpl_node *tn;
int id=0;
char *name,*names[] = { \"joe\",\"bob\",\"cary\" };
tn = tpl_map(\"A(is)\",&id,&name);
for(name=names[0]; id < 3; name=names[++id]) {
tpl_pack(tn,1);
}
tpl_dump(tn,TPL_FILE,\"users.tpl\");
tpl_free(tn);
}
相反:
/* Reloading ids and usernames */
#include <tpl.h>
int main(int argc,char *argv[]) {
tpl_node *tn;
int id;
char *name;
tn = tpl_map(\"A(is)\",&name);
tpl_load(tn,\"users.tpl\");
while ( tpl_unpack(tn,1) > 0 ) {
printf(\"id %d,user %s\\n\",id,name);
free(name);
}
tpl_free(tn);
}
另一种选择是在ASN.1中编码和解码,而不是自己进行编码。另外,您可能会得到遵循以下标准的布朗尼分。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。