簡體   English   中英

C / UNIX進程間通信使用管道發送字符串

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM