C/UNIX 进程间通信用管道发送字符串
C/UNIX Interprocess communication sending a string with pipe
我正在编写一个代码,其中 children 和 parent 应该互相提供时间信息,接收者应该打印 it.When 我在 parent 过程中找到时间并尝试在 parent 进程上打印它 它工作 fine.But 当我尝试通过管道发送它时它写了一行带有奇怪的问号和 z letter.I 评论最后一行以防万一有人试图执行代码。抱歉,代码乱七八糟,但我无法在当前键盘上修复它。
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include<signal.h>
#include<stdint.h>
#include<string.h>
#include<time.h>
void formatted_time(char* sender_name, char* receiver_name, char output[]);
void formatted_time( char* sender_name , char* receiver_name, char output[])
{
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80 , "%Y-%m-%d %H:%M:%S",
nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv)
{
char* parent="Parent";
char* child1="Child1";
char* child2="Child2";
char result[80];
char buffer[80];
int firstchild,secondchild,read1,read2,read3;
firstchild=fork();
int mypipe[2];
int mypipe2[2];
int mypipe3[2];
if(pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
if(firstchild == 0) //first child
{
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1=read(mypipe[0],buffer,sizeof(buffer));
printf("%s\n",buffer);
}else{
secondchild=fork(); //Creating second child
if(secondchild == 0) //2nd child
{
sleep(6);
}else{ //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent,child1,result);
write(mypipe[1],result,strlen(result)+1);
//printf("%s\n",result);
您的问题是在创建管道之前fork
调用。所以实际上你 read
什么也没读,而你的 printf
打印分配 buffer
的堆栈上的垃圾。
您的代码已修复。我还在父项中添加了一个 wait
调用,以避免子项无处不在地打印到控制台 :)
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
void formatted_time(char *sender_name,char *receiver_name, char output[]) {
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80, "%Y-%m-%d %H:%M:%S", nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv) {
char* parent="Parent";
char* child1="Child1";
char result[80];
char buffer[80];
int firstchild, secondchild, read1;
int mypipe[2];
if (pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
firstchild=fork();
if (firstchild == 0) { // first child
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1 = read(mypipe[0], buffer, sizeof(buffer));
printf("%d %s\n", read1, buffer);
} else {
secondchild=fork(); //Creating second child
if(secondchild == 0) { //2nd child
sleep(6);
} else { //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent, child1, result);
int w;
w = write(mypipe[1], result, strlen(result)+1);
printf("%d bytes written\n", w);
wait(NULL);
}
}
return 0;
}
您在创建管道之前分叉了第一个 child。因此,您创建了两个不同的管道:一个在 parent 中,一个在 child 中。之后,如果从第一个child创建的管道读取,read
returns为0,表示没有读取数据。因此,缓冲区中的数据无效并且printf
被禁止。始终检查 API 个调用的 return 代码!
用户 "nsilent22" 已经提供了很好的 clean-up 您的代码。在末尾添加 3 个右括号 }
以关闭所有块后,您至少在创建管道后移动叉子:
firstchild=fork();
if (firstchild == 0) { // first child
并且在读取调用中,您应该检查 return 代码:
read1=read(mypipe[0],buffer,sizeof(buffer));
if (read1 <= 0) {
printf("read failed with code %d\n, ", read1);
} else {
printf("%s\n",buffer);
}
我正在编写一个代码,其中 children 和 parent 应该互相提供时间信息,接收者应该打印 it.When 我在 parent 过程中找到时间并尝试在 parent 进程上打印它 它工作 fine.But 当我尝试通过管道发送它时它写了一行带有奇怪的问号和 z letter.I 评论最后一行以防万一有人试图执行代码。抱歉,代码乱七八糟,但我无法在当前键盘上修复它。
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include<signal.h>
#include<stdint.h>
#include<string.h>
#include<time.h>
void formatted_time(char* sender_name, char* receiver_name, char output[]);
void formatted_time( char* sender_name , char* receiver_name, char output[])
{
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80 , "%Y-%m-%d %H:%M:%S",
nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv)
{
char* parent="Parent";
char* child1="Child1";
char* child2="Child2";
char result[80];
char buffer[80];
int firstchild,secondchild,read1,read2,read3;
firstchild=fork();
int mypipe[2];
int mypipe2[2];
int mypipe3[2];
if(pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
if(firstchild == 0) //first child
{
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1=read(mypipe[0],buffer,sizeof(buffer));
printf("%s\n",buffer);
}else{
secondchild=fork(); //Creating second child
if(secondchild == 0) //2nd child
{
sleep(6);
}else{ //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent,child1,result);
write(mypipe[1],result,strlen(result)+1);
//printf("%s\n",result);
您的问题是在创建管道之前fork
调用。所以实际上你 read
什么也没读,而你的 printf
打印分配 buffer
的堆栈上的垃圾。
您的代码已修复。我还在父项中添加了一个 wait
调用,以避免子项无处不在地打印到控制台 :)
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
void formatted_time(char *sender_name,char *receiver_name, char output[]) {
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80, "%Y-%m-%d %H:%M:%S", nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv) {
char* parent="Parent";
char* child1="Child1";
char result[80];
char buffer[80];
int firstchild, secondchild, read1;
int mypipe[2];
if (pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
firstchild=fork();
if (firstchild == 0) { // first child
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1 = read(mypipe[0], buffer, sizeof(buffer));
printf("%d %s\n", read1, buffer);
} else {
secondchild=fork(); //Creating second child
if(secondchild == 0) { //2nd child
sleep(6);
} else { //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent, child1, result);
int w;
w = write(mypipe[1], result, strlen(result)+1);
printf("%d bytes written\n", w);
wait(NULL);
}
}
return 0;
}
您在创建管道之前分叉了第一个 child。因此,您创建了两个不同的管道:一个在 parent 中,一个在 child 中。之后,如果从第一个child创建的管道读取,read
returns为0,表示没有读取数据。因此,缓冲区中的数据无效并且printf
被禁止。始终检查 API 个调用的 return 代码!
用户 "nsilent22" 已经提供了很好的 clean-up 您的代码。在末尾添加 3 个右括号 }
以关闭所有块后,您至少在创建管道后移动叉子:
firstchild=fork();
if (firstchild == 0) { // first child
并且在读取调用中,您应该检查 return 代码:
read1=read(mypipe[0],buffer,sizeof(buffer));
if (read1 <= 0) {
printf("read failed with code %d\n, ", read1);
} else {
printf("%s\n",buffer);
}