简体   繁体   English

fork()-父子进程访问的多个文件

[英]fork()- multiple files accessed by parent & child processes

For educational purposes, I wrote a program that forks a process and ... 出于教育目的,我编写了一个程序来分叉流程并...

  1. the child continuously reads 3 files, prints the contents, sleeps for 10ms. 孩子连续读取3个文件,打印内容,睡眠10毫秒。
  2. the parent keeps a counter for each file. 父母为每个文件保留一个计数器。 each file also has a delay time associated with it. 每个文件还具有与之关联的延迟时间。 each time a file's timer expires, the counter is incremented and the file is overwritten with the 每次文件的计时器到期时,计数器都会递增,并且文件会被
    new counter value. 新的计数器值。 Each delay value is different, so all 3 files get updated at different rates. 每个延迟值都不同,因此所有3个文件的更新速率都不同。

The problem is, the counters only increment for a short time, and everything freezes after a few seconds. 问题是,计数器仅会增加一小段时间,并且几秒钟后所有内容都会冻结。 Can anyone give a good explanation of what is happening here? 任何人都可以很好地解释这里发生的事情吗?

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h> 
#include <sys/time.h>

#define CHAN1WAIT 100000
#define CHAN2WAIT 750000
#define CHAN3WAIT 1000000
#define NCHAN 3

FILE *chanfiles[NCHAN] = {NULL, NULL, NULL};                                      //file pointers for fake 'devices'
char *filenames[NCHAN] = {"_chan1tmpfile_", "_chan2tmpfile_", "_chan3tmpfile_"}; 
int chanwait[NCHAN] = {CHAN1WAIT, CHAN2WAIT, CHAN3WAIT};                          //time it takes for each 'device' to be updated with a new value
int chancount[NCHAN] = {0, 0, 0};  //value for each device    
int clrcount = NCHAN * 8;

uint8_t chan1;

int read_chan (int chan)
{
    char buf[4];
    char c;
    int i, ret;
    short count = 0;
    uint8_t set = 0;
    char * retstr;

    while (! set)
    {
        if (chanfiles[chan] == NULL) //if file is not in use
        {
            if ((chanfiles[chan] = fopen(filenames[chan], "r")) == NULL)
            {
                printf("Error opening file %s for reading.\n%s\n", filenames[chan], strerror(errno));
                exit(-1);
            }

            while ((c = fgetc(chanfiles[chan])) != EOF)
            {
                buf[count] = c;
                count++;
            }
            fclose(chanfiles[chan]);
            chanfiles[chan] = NULL;
            retstr = malloc(count + 1);
            for (i = 0; i < count; i++) retstr[i] = buf[i];
            ret = atoi(retstr);
            free(retstr);
            set = 1;
        }
    }
    return ret;
}

void write_chan (int chan)
{
    uint8_t set = 0;
    while (! set)
    {
        if (chanfiles[chan] == NULL) //if file is not in use
        {
            if ((chanfiles[chan] = fopen(filenames[chan], "w")) == 0)
            {
                printf("Error opening file %s for writing.\n%s\n", filenames[chan], strerror(errno));
                exit(-1);
            }

            if (fprintf(chanfiles[chan], "%d", chancount[chan]) < 0)
            {
                printf("Error writing to file %s:\n%s\n", filenames[chan], strerror(errno));
                exit(-1);
            }

            fclose(chanfiles[chan]);
            chanfiles[chan] = NULL;
            set = 1;
        }
    }
}

time_t get_usecs()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
        return tv.tv_sec + tv.tv_usec;
}

int main (int argc, char * argv[])
{
    pid_t pid;
    time_t curtime;
    int i;

    for (i = 0; i < NCHAN; i++) write_chan(i);

    printf("\nChannel:");
    for (i = 0; i < NCHAN; i++) printf("%8d", i);
    printf("\n  Value:");

    pid = fork();

// This process reads all 3 files, prints the values,
// then sleeps for 10ms, in an infinite loop.
    if (pid == 0)
    {
        int j;
        while (1)
        {
            uint8_t set;
            for (j = 0; j < NCHAN; j++)
            {
                int value;
                set = 0;
                value = read_chan(j);
                printf("%8d", value);
            }
            fflush(stdout);
            usleep(10000);
            for (j = 0; j < clrcount; j++) printf("\b"); fflush(stdout);
        }
    }

// This process updates the values of all 3 files at 
// different rates, based on the value in chanwait[]
// for each file.
    else
    {
        time_t timers[NCHAN];
        int i;
        for (i = 0; i < NCHAN; i++) timers[i] = get_usecs();

        while (1)
        {
            for (i = 0; i < NCHAN; i++)
            {
                if ((get_usecs() - timers[i]) >= chanwait[i])
                {
                    chancount[i]++;
                    write_chan(i);
                    timers[i] = get_usecs();
                }
            }
        }
    }
}

I am not sure this is your only problem, but your get_usecs function is suspect. 我不确定这是您唯一的问题,但是您的get_usecs函数get_usecs怀疑。 You probably meant this 你可能是这个意思

return tv.tv_sec * 1000000 + tv.tv_usec;

Rather than 而不是

return tv.tv_sec + tv.tv_usec;

Although, note that time_t is only guaranteed to be large enough for the time in seconds, not the number of microseconds as you have used it. 尽管请注意,time_t仅能保证以秒为单位的时间足够大,而不是您使用时所用的微秒数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM