读取后 FIFO 管道内容包含错误的字符
FIFO pipe content contains wrong chars after read
我创建了一个程序,它在 10 个线程上并行查找整数数组中的最大值,并且有一个 parent 和一个 child 进程。 Child 计算区间的最大值(数组有 1000 个元素)最大值并写入命名管道,parent 只是从 FIFO 中读取最大值并打印它。当我想从 FIFO 中读取内容时,读取的内容包含一些错误的字符,但输入的字符串是正确的。
我怎样才能避免这个问题?
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#define max 1000
#define Th_max 10
int numbers[max];
int max_num[Th_max] = { 0 };
int thread_no = 0;
void *maximum(void* arg)
....
}
int main()
{
int maxs = 0;
int i;
char buf[32];
int fd, ret;
int pipefd[2];
pid_t cpid;
pthread_t threads[Th_max];
srand(time(0));
for( i = 0; i < 1000; i++ ) {
numbers[i] = rand();
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(-1);
}
if (cpid == 0) {
printf("PID: %d : Child process \n",getpid());
for (i = 0; i < Th_max; i++)
pthread_create(&threads[i], NULL,
maximum, (void*)NULL);
for (i = 0; i < Th_max; i++)
pthread_join(threads[i], NULL);
for (i = 0; i < Th_max; i++) {
if (max_num[i] > maxs)
maxs = max_num[i];
}
fd=open("Pipe",O_RDWR);
sprintf(buf, "%d", maxs);
printf("PID: %d :Write this to FIFO: %s:%ld\n",getpid(),buf,strlen(buf));
write(fd,buf,strlen(buf));
exit(0);
} else {
printf("PID: %d : Parent process\n",getpid());
ret=mkfifo("Pipe",00666);
if (ret == -1) {
perror("mkfifo()");
exit(-1);
}
fd=open("Pipe",O_RDWR);
if (fd == -1) {
perror("open() error!");
exit(-1);
}
wait(NULL);
ret=read(fd,buf,32);
printf("PID: %d :Read %d byte: %s\n",getpid(),ret,buf);
close(fd);
unlink("LA3WXZ");
}
return 0;
}
OP 的代码试图将字符数组打印为 字符串 。它不是所需的 字符串 ,因为它在第 10 个字符后缺少 空字符 ..
改为使用 精度 来限制字符数组的打印。
//printf("PID: %d :Read %d byte: %s\n",getpid(),ret,buf);
printf("PID: %d :Read %d byte: %.*s\n",getpid(),ret, ret, buf);
// ^^ ^^^ precision
或者最多只读少1个字符并追加0。
// ret=read(fd,buf,32);
ret = read(fd, buf, sizeof buf - 1);
if (ret >= 0) {
buf[ret] = '[=11=]';
...
或发送空字符。
// write(fd,buf,strlen(buf));
write(fd,buf,strlen(buf) + 1);
或者...
注意:getpid()
不一定 return 和 int
。 Cast to a wide type 并打印。
printf("%lld\n", (long long) getpid());
我创建了一个程序,它在 10 个线程上并行查找整数数组中的最大值,并且有一个 parent 和一个 child 进程。 Child 计算区间的最大值(数组有 1000 个元素)最大值并写入命名管道,parent 只是从 FIFO 中读取最大值并打印它。当我想从 FIFO 中读取内容时,读取的内容包含一些错误的字符,但输入的字符串是正确的。 我怎样才能避免这个问题?
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#define max 1000
#define Th_max 10
int numbers[max];
int max_num[Th_max] = { 0 };
int thread_no = 0;
void *maximum(void* arg)
....
}
int main()
{
int maxs = 0;
int i;
char buf[32];
int fd, ret;
int pipefd[2];
pid_t cpid;
pthread_t threads[Th_max];
srand(time(0));
for( i = 0; i < 1000; i++ ) {
numbers[i] = rand();
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(-1);
}
if (cpid == 0) {
printf("PID: %d : Child process \n",getpid());
for (i = 0; i < Th_max; i++)
pthread_create(&threads[i], NULL,
maximum, (void*)NULL);
for (i = 0; i < Th_max; i++)
pthread_join(threads[i], NULL);
for (i = 0; i < Th_max; i++) {
if (max_num[i] > maxs)
maxs = max_num[i];
}
fd=open("Pipe",O_RDWR);
sprintf(buf, "%d", maxs);
printf("PID: %d :Write this to FIFO: %s:%ld\n",getpid(),buf,strlen(buf));
write(fd,buf,strlen(buf));
exit(0);
} else {
printf("PID: %d : Parent process\n",getpid());
ret=mkfifo("Pipe",00666);
if (ret == -1) {
perror("mkfifo()");
exit(-1);
}
fd=open("Pipe",O_RDWR);
if (fd == -1) {
perror("open() error!");
exit(-1);
}
wait(NULL);
ret=read(fd,buf,32);
printf("PID: %d :Read %d byte: %s\n",getpid(),ret,buf);
close(fd);
unlink("LA3WXZ");
}
return 0;
}
OP 的代码试图将字符数组打印为 字符串 。它不是所需的 字符串 ,因为它在第 10 个字符后缺少 空字符 ..
改为使用 精度 来限制字符数组的打印。
//printf("PID: %d :Read %d byte: %s\n",getpid(),ret,buf);
printf("PID: %d :Read %d byte: %.*s\n",getpid(),ret, ret, buf);
// ^^ ^^^ precision
或者最多只读少1个字符并追加0。
// ret=read(fd,buf,32);
ret = read(fd, buf, sizeof buf - 1);
if (ret >= 0) {
buf[ret] = '[=11=]';
...
或发送空字符。
// write(fd,buf,strlen(buf));
write(fd,buf,strlen(buf) + 1);
或者...
注意:getpid()
不一定 return 和 int
。 Cast to a wide type 并打印。
printf("%lld\n", (long long) getpid());