c - pipeline() 将结构从子级发送到父级。 read() 中的象形文字;

标签 c struct pipe fork exec

我想通过结构将测量数据从子进程发送到父进程。父进程必须打印10个测量数据的平均值。

funcs.h中的结构体数据:

struct data{
int nr;
float temp;
float bst;
float abst;
};

uebung2_1.c(主要):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#include "funcs.h"

#define READ_END 0
#define WRITE_END 1
#define CHILD "./sohn"

int main(){
    int w_status, pid_fork, i, k;
    double midT, midB, midA;
    int pfd[2];
    struct data buf;

    if(pipe(pfd) == -1){
        perror("ERROR creating a pipe\n");
        exit(EXIT_FAILURE);
    }

    pid_fork = fork();
    switch(pid_fork){
        case(-1):
            perror("fork()");
            return EXIT_FAILURE;
        case(0):
            dup2(pfd[WRITE_END], STDOUT_FILENO);
            close(pfd[READ_END]);
            execlp(CHILD,CHILD,NULL);
            perror("exec is failed");
            break;
        default:
            close(pfd[WRITE_END]);
            printf("Sohn gestartet mit PID %d\n", pid_fork);
            midT = midB = midA = 0;
            i = k = 0;
            while(1){
                read(pfd[READ_END],&buf,sizeof(struct data));
                midT += buf.temp;
                midB += buf.bst;
                midA += buf.abst;
                i++;
                if(i == 10){
                    midT /=10;
                    midB /=10;
                    midA /=10;
                    printf("Messung. %4i: Temp.: %4.1lf, Beleucht.: %4lf, Abstand: %3.1lf\n",k++, midT, midB, midA);
                    midT = midB = midA = 0;
                    i = 0;
                }
            }
            while(i != -1){
                i = wait(&w_status);
                if(i != -1)
                    printf("\nSohn beendet. Exit Status: %x Nummer des Sohn-Prozesses %d",
                        (w_status>>8) & 0xff, i);
                    else
                        printf("\nLetzter Sohn beendet!\n");
            }
        }
    return 0;
}

子 sohn 进程每 500ns 通过 Linux 中断发送一次测量数据。我先用char数组测试了一下,成功了。

sohn.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#include <sys/time.h>
#include "funcs.h"

#define INTERVAL 500000

int howmany = 0;

void alarm_wakeup (int i)
{
    struct itimerval tout_val;
    howmany += INTERVAL;
    tout_val.it_interval.tv_sec = 0;
    tout_val.it_interval.tv_usec = 0;
    tout_val.it_value.tv_sec = 0;
    tout_val.it_value.tv_usec = INTERVAL;
    setitimer(ITIMER_REAL, &tout_val,0);
}

void exit_func (int i)
{
    signal(SIGINT,exit_func);
    exit(0);
}



int main(){

    struct data mess;
    struct itimerval tout_val;
    tout_val.it_interval.tv_sec = 0;
    tout_val.it_interval.tv_usec = 0;
    tout_val.it_value.tv_sec = 0;
    tout_val.it_value.tv_usec = INTERVAL;
    setitimer(ITIMER_REAL, &tout_val,0);
    signal(SIGALRM,alarm_wakeup);
    signal(SIGINT,exit_func);

    srand(time(0));
    mess.nr = 0;
    while (1) {
        mess.nr++;
        mess.temp = (rand()%1001)/10 - 20;
        mess.bst = rand()%1000 + 1;
        mess.abst = rand()%26 + 4;
        write(STDIN_FILENO,&mess, sizeof(struct data));
        sleep(10);
    }

    exit(0);
}

输出:

Sohn gestartet mit PID 3488
�BhB�A@��@�A�B�!DA@ATCpA�B@D A4B�C�A0A@#D0dB�sDA        4B��CpA
��\D�A^C

使用 strace 输出:

strace ./uebung2_1 
execve("./uebung2_1", ["./uebung2_1"], [/* 78 vars */]) = 0
brk(0)                                  = 0x8320000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7791000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=109872, ...}) = 0
mmap2(NULL, 109872, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7776000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\233\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1754876, ...}) = 0
mmap2(NULL, 1759868, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75c8000
mmap2(0xb7770000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a8000) = 0xb7770000
mmap2(0xb7773000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7773000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75c7000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb75c7940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7770000, 8192, PROT_READ)   = 0
mprotect(0x8049000, 4096, PROT_READ)    = 0
mprotect(0xb77b7000, 4096, PROT_READ)   = 0
munmap(0xb7776000, 109872)              = 0
pipe([3, 4])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb75c79a8) = 3436
close(4)                                = 0
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 8), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7790000
write(1, "Sohn gestartet mit PID 3436\n", 28Sohn gestartet mit PID 3436
) = 28
read(3, �B�C�A@A4D�@
                    B�D@AHB�nD�A�A�C�B�C`ApB�▒D��A'C@A  ,B��C�A
���C�A
      �B$D�A
PA�C�AB�LD�A<B��CA��@D ApA@gD�A�AD@A^CProcess 3435 detached
 <detached ...>

我用 ctrl+c 终止了该进程。为什么是象形文字?

-------------------------------------------------------- -------------------------------------------

更新: 我在 child (sohn.c) 中写入了标准输入,但它必须写入输出。感谢Joachim Pileborg

最佳答案

我在子进程(sohn.c)中写入了标准输入,但它必须写入输出。感谢Joachim Pileborg

- 夷为平地

关于c - pipeline() 将结构从子级发送到父级。 read() 中的象形文字;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37022510/

相关文章:

c - 多进程和管道

c - freeDiameter - 事件时间戳

c++ - 将有符号整数位复制到无符号整数的有效方法

java - JNA 和结构体中的 boolean 数组

c - 将结构中的指针设置为 null

Linux 命令 : Why does the redirection operator - | i. e。管道在这里失败?

c - printf() 似乎正在破坏我的数据

c - 如何从其他目录中将头文件包含在.c中

c - 高度平衡C树

具有大对象的 Python 多处理管道将挂起