在 C 中读取结构体并将其写入管道
我正在尝试编写一个由字符数组、整数值和指向管道的指针组成的结构。该结构表示单链表中的一个节点。
//Define a linked-list node object
typedef struct node{
char word[128];
int frequency;
struct node *next;
} NODE;
该程序的目标是使用管道将节点从多个并发子进程传递到父进程。我实现的管道结构似乎可以很好地处理常规字符数组,但如果我尝试传递整个节点对象,则无法正常工作。
//for each file argument, create a child process
for (i = 1; i < argc; i ++)
{
pipe(p[i-1]);
pid = fork();
if (pid == 0)
{
//child process
close(p[i-1][0]);
NODE *tmp;
NODE *out = freqCheck(argv[i], tmp);
write(p[i-1][1], out, sizeof(NODE));
exit(0);
}
}
if (pid > 0){
//parent process
int j;
for (j = 0; j < argc-1; j++)
{
close(p[j][1]);
NODE *tmp;
read(p[j][0], tmp, sizeof(NODE));
printf("%s\n", tmp->word);
}
}
当父进程尝试从管道读取并解释结构的属性之一时,我只会返回空值。
我使用 2 元素整数数组的数组来跟踪每个子进程的管道。上面的 printf 语句返回 null 恢复时间。
知道我做错了什么吗?
FrqCheck 方法的代码:
//Method for determining the most occuring word
NODE * freqCheck(char *file, NODE *max)
{
int i;
FILE *f;
char str[128];
//Set up head and tail nodes
NODE *head = NULL;
NODE *tail = NULL;
if ((f = fopen(file, "r")) == NULL)
{
//sprintf(output, "%s could not be opened.", file);
}else
{
//scan each word of the input file
while(fscanf(f, "%s ", str) != EOF)
{
//if the linked-list has no nodes, create one
if (head == NULL)
{
NODE *n;
n = (NODE *)malloc(sizeof(NODE));
strcpy(n->word, str);
n->frequency = 1;
n->next = NULL;
head = n;
tail = n;
}else{ //search the linked list for the found word.
NODE *current = head;
int found = 0;
while((current != NULL) && (found == 0))
{
//if the word is found increment the frequency
if (strcmp(current->word, str) == 0)
{
current->frequency ++;
found = 1;
}else
{
current = current->next;
}
}
//if the word is not found, create a node and add to the liked-list
if (found == 0)
{
NODE *new;
new = (NODE *)malloc(sizeof(NODE));
strcpy(new->word, str);
new->frequency = 1;
new->next = NULL;
tail->next = new;
tail = new;
}
}
}
//traverse the linked-list and find the word with the maximum frequency
NODE *tmp = head;
max = tmp;
while (tmp != NULL)
{
if (tmp->frequency > max->frequency)
{
max = tmp;
}else
{
tmp = tmp->next;
}
}
//sprintf(output, "%s %s %d", file, max->word, max->frequency);
}
//printf("%s\n", max->word);
return max;
}
I'm attempting to write a structure consisting of a an array of characters, an integer value, and a pointer to a pipe. The structure represents a node in a singly linked list.
//Define a linked-list node object
typedef struct node{
char word[128];
int frequency;
struct node *next;
} NODE;
The object of the program is to use a pipe to pass a node from several concurrent child processes to the parent. The pipe structure I've implemented seems to work fine with regular character arrays but won't work if I try to pass the entire node object.
//for each file argument, create a child process
for (i = 1; i < argc; i ++)
{
pipe(p[i-1]);
pid = fork();
if (pid == 0)
{
//child process
close(p[i-1][0]);
NODE *tmp;
NODE *out = freqCheck(argv[i], tmp);
write(p[i-1][1], out, sizeof(NODE));
exit(0);
}
}
if (pid > 0){
//parent process
int j;
for (j = 0; j < argc-1; j++)
{
close(p[j][1]);
NODE *tmp;
read(p[j][0], tmp, sizeof(NODE));
printf("%s\n", tmp->word);
}
}
When the parent process attempts to read from the pipe and interpret one of the attributes of the structure, I just get null values back.
I'm using an array of 2 element integer arrays to keep track of each child processes' pipe. The printf statement above returns null revery time.
Any idea what I'm doing wrong?
Code for the FrqCheck method:
//Method for determining the most occuring word
NODE * freqCheck(char *file, NODE *max)
{
int i;
FILE *f;
char str[128];
//Set up head and tail nodes
NODE *head = NULL;
NODE *tail = NULL;
if ((f = fopen(file, "r")) == NULL)
{
//sprintf(output, "%s could not be opened.", file);
}else
{
//scan each word of the input file
while(fscanf(f, "%s ", str) != EOF)
{
//if the linked-list has no nodes, create one
if (head == NULL)
{
NODE *n;
n = (NODE *)malloc(sizeof(NODE));
strcpy(n->word, str);
n->frequency = 1;
n->next = NULL;
head = n;
tail = n;
}else{ //search the linked list for the found word.
NODE *current = head;
int found = 0;
while((current != NULL) && (found == 0))
{
//if the word is found increment the frequency
if (strcmp(current->word, str) == 0)
{
current->frequency ++;
found = 1;
}else
{
current = current->next;
}
}
//if the word is not found, create a node and add to the liked-list
if (found == 0)
{
NODE *new;
new = (NODE *)malloc(sizeof(NODE));
strcpy(new->word, str);
new->frequency = 1;
new->next = NULL;
tail->next = new;
tail = new;
}
}
}
//traverse the linked-list and find the word with the maximum frequency
NODE *tmp = head;
max = tmp;
while (tmp != NULL)
{
if (tmp->frequency > max->frequency)
{
max = tmp;
}else
{
tmp = tmp->next;
}
}
//sprintf(output, "%s %s %d", file, max->word, max->frequency);
}
//printf("%s\n", max->word);
return max;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(3)
您需要考虑两件事:
1) 执行协调:
这就是锁、信号量、事件等的用途。它们按照指令(您的代码行)运行的顺序强制执行命令。正是出于这个原因,这些版本有一些在进程之间运行的版本,就像在线程中运行的版本一样。你需要一个信号量——当节点完全传输时,写入进程应该 post() sem,而读取进程应该在尝试读取下一个节点之前在 sem 上 wait() 。
2)内存:
进程不共享地址空间。因此,读取器和写入器进程拥有的堆是不同的内存块。管道工作正常,但它就像一个套接字——将对象序列化和反序列化为原始字节流的所有麻烦。考虑到您的结构有多小,您可以考虑的另一件事是共享内存。
最后要考虑的一件事是:指向节点结构中“下一个”节点的指针需要在子进程中更新。同样,它将把这些节点复制到其自己的地址空间中的位置,因此必须相应地更新“下一个”指针。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您在哪里为
NODE
结构分配存储空间?freqCheck
是否分配存储空间?在父进程中,当您调用read()
然后调用printf
时,您传入了一个未初始化的NODE
指针,所以您当然得到未定义的行为。Where are you allocating storage for your
NODE
structures? DoesfreqCheck
allocate storage? In the parent process, when you callread()
and thenprintf
, you pass in an uninitializedNODE
pointer, so of course you're getting undefined behavior.