簡體   English   中英

fork()-父子進程訪問的多個文件

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

出於教育目的,我編寫了一個程序來分叉流程並...

  1. 孩子連續讀取3個文件,打印內容,睡眠10毫秒。
  2. 父母為每個文件保留一個計數器。 每個文件還具有與之關聯的延遲時間。 每次文件的計時器到期時,計數器都會遞增,並且文件會被
    新的計數器值。 每個延遲值都不同,因此所有3個文件的更新速率都不同。

問題是,計數器僅會增加一小段時間,並且幾秒鍾后所有內容都會凍結。 任何人都可以很好地解釋這里發生的事情嗎?

#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();
                }
            }
        }
    }
}

我不確定這是您唯一的問題,但是您的get_usecs函數get_usecs懷疑。 你可能是這個意思

return tv.tv_sec * 1000000 + tv.tv_usec;

而不是

return tv.tv_sec + tv.tv_usec;

盡管請注意,time_t僅能保證以秒為單位的時間足夠大,而不是您使用時所用的微秒數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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