[英]C/UNIX Interprocess communication sending a string with pipe
我正在編寫一個代碼,其中孩子和父母應該給彼此提供時間信息,接收者應該打印它。當我在父進程上找到時間並嘗試在父進程上打印它工作正常。但是當我嘗試發送它時通過管道,它寫了一行帶有奇怪的問號和az字母。如果有人試圖執行代碼,我會評論最后一行。 煩惱的代碼,但我無法修復我當前的鍵盤。
#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;
}
在創建管道之前,您正在分叉第一個孩子。 因此,您創建了兩個不同的管道:一個在父級中,另一個在子級中。 之后,如果從第一個子節點中創建的管道read
,則read
返回0,表示沒有讀取任何數據。 因此,緩沖區中的數據無效,禁止printf
。 始終檢查API調用的返回碼!
用戶“nsilent22”已經為您的代碼提供了良好的清理。 在最后添加3個關閉括號}
以關閉所有塊后,您至少在創建管道后移動叉子:
firstchild=fork();
if (firstchild == 0) { // first child
在讀取調用時,您應該檢查返回代碼:
read1=read(mypipe[0],buffer,sizeof(buffer));
if (read1 <= 0) {
printf("read failed with code %d\n, ", read1);
} else {
printf("%s\n",buffer);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.