[英]pipe with file fread & fwrite send file from one process to another
我實現了一個 pipe,它從一個 100MB 的進程數據文件大小“傳輸”到另一個進程。
從一個過程到另一個過程的整個發送效果很好,但它需要很長時間......大約 2.5 分鍾以上。
我想將我的函數更改為 fread&fwrite 以使 function 更快,而不是每次讀取一個字符我如何使用 pd[0] & pd[1] 來完成它,但我幾乎不明白如何更改它
任何幫助將不勝感激!
這是我的代碼:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int fd[2];
pid_t childpid;
char readbuffer[65535];
pipe(fd);
if ((childpid = fork()) == -1) {
perror("fork");
exit(1);
}
if (childpid == 0) {
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
FILE *fp2 = fopen("data.txt", "rb");
if (fp2 == NULL) {
//handle error here
return -1;
}
int c;
while ((c = getc(fp2)) != EOF) {
if ((write(fd[1], &c, 1)) < 1) {
fprintf(stderr, "Write to pipe failed.\n");
perror("write");
exit(EXIT_FAILURE);
}
}
} else {
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
char *new_data = "new_data.txt";
FILE *fp = fopen(new_data, "wb");
ssize_t num_bytes;
while (num_bytes = (read(fd[0], readbuffer, sizeof(readbuffer))) > 0) {
fwrite(readbuffer, 1, num_bytes, fp);
memset(readbuffer, 0, 65535);
}
fclose(fp);
}
return 0;
}
編輯第 2 輪:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int fd[2];
pid_t childpid;
char readbuffer[1024];
pipe(fd);
if ((childpid = fork()) == -1) {
perror("fork");
exit(1);
}
if (childpid == 0) {
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
FILE *fp2 = fopen("data.txt", "rb");
if (fp2 == NULL) {
//handle error here
return -1;
}
int c;
// while ((c = getc(fp2)) != EOF) {
// if ((write(fd[1], &c, 1)) < 1) {
// fprintf(stderr, "Write to pipe failed.\n");
// perror("write");
// exit(EXIT_FAILURE);
// }
// }
ssize_t num_bytes;
while ((num_bytes = fread(readbuffer, sizeof(readbuffer), 1024,fp2)) > 0) {
fwrite(readbuffer, 1, num_bytes, fd[1]);
//memset(readbuffer, 0, 65535);
}
} else {
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
char *new_data = "new_data.txt";
FILE *fp = fopen(new_data, "wb");
ssize_t num_bytes;
while ((num_bytes = read(fd[0], readbuffer, sizeof(readbuffer))) > 0) {
fwrite(readbuffer, 1, num_bytes, fp);
//memset(readbuffer, 0, 65535);
}
fclose(fp);
}
return 0;
}
幾個問題...
在您的原始代碼中,主要問題 [速度方面] 是使用長度為 1 的read
或write
。
此外,盡管 stream 可能會稍微補償fgetc
,但它仍然是一次一個字節。
我想出的解決方案是實施 William Pursell 的建議:使用fdopen
將 stdio stream(即FILE *
)附加到 pipe。
我們可以為父母和孩子這樣做。
然后,只需在兩個進程中循環fread/fwrite
即可。
請注意,父級和應該執行fclose
。
並且,父母應該等待孩子完成(例如waitpid
)。
這是修改后的代碼:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#ifdef DEBUG
#define dbgprt(_fmt...) \
do { \
int sverr = errno; \
fprintf(stderr,_fmt); \
errno = sverr; \
} while (0)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif
int
main(void)
{
int fd[2];
FILE *fpinp;
FILE *fpout;
pid_t childpid;
int status;
ssize_t rlen;
ssize_t wlen;
#if 0
char buffer[65535];
#else
char buffer[1024];
#endif
setlinebuf(stdout);
setlinebuf(stderr);
pipe(fd);
if ((childpid = fork()) == -1) {
perror("fork");
exit(1);
}
if (childpid == 0) {
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
fpinp = fopen("data.txt", "rb");
if (fpinp == NULL) {
perror("child/fopen");
exit(7);
}
fpout = fdopen(fd[1],"wb");
if (fpout == NULL) {
perror("child/fdopen");
exit(8);
}
while (1) {
rlen = fread(buffer,1,sizeof(buffer),fpinp);
dbgprt("child: LOOP rlen=%zd\n",rlen);
if (rlen < 0) {
perror("child/fread");
exit(9);
}
if (rlen <= 0)
break;
wlen = fwrite(buffer,1,rlen,fpout);
dbgprt("child: LOOP wlen=%zd\n",wlen);
if (wlen < 0) {
perror("child/fwrite");
exit(9);
}
}
fclose(fpinp);
fclose(fpout);
exit(0);
}
else {
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
char *new_data = "new_data.txt";
fpout = fopen(new_data, "wb");
if (fpout == NULL) {
perror("parent/fopen");
exit(3);
}
fpinp = fdopen(fd[0],"rb");
if (fpinp == NULL) {
perror("parent/fdopen");
exit(4);
}
while (1) {
rlen = fread(buffer, 1, sizeof(buffer), fpinp);
dbgprt("parent: LOOP rlen=%zd\n",rlen);
if (rlen < 0) {
perror("parent/fread");
exit(5);
}
if (rlen <= 0)
break;
wlen = fwrite(buffer, 1, rlen, fpout);
dbgprt("parent: LOOP wlen=%zd\n",wlen);
if (wlen < 0) {
perror("parent/fwrite");
exit(6);
}
}
fclose(fpinp);
fclose(fpout);
waitpid(childpid,&status,0);
dbgprt("status=%8.8X\n",status);
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.