select()在超时结构中指定的间隔后不超时

select()在超时结构中指定的间隔后不超时,c,linux,C,Linux,我正在尝试中提供的示例的稍加修改的版本 我的目标基本上是使用父进程中的select()监视事件fd,然后执行read()调用。从输出来看,父进程的select调用似乎仅在子进程执行某些写入操作时才作用于fd。如果子进程不执行任何操作,即如果它处于休眠状态,则父进程会阻塞select调用,并且即使已过5秒,它也不会超时。这里我还缺少什么吗?因为tv结构的tv\u usec成员没有初始化,它将有一个不确定的值 这个不确定的值几乎可以被视为随机或垃圾,并可能导致未定义的行为 而未定义的行为可能会像在您

我正在尝试中提供的示例的稍加修改的版本


我的目标基本上是使用父进程中的
select()
监视事件fd,然后执行
read()
调用。从输出来看,父进程的select调用似乎仅在子进程执行某些写入操作时才作用于fd。如果子进程不执行任何操作,即如果它处于休眠状态,则父进程会阻塞select调用,并且即使已过5秒,它也不会超时。这里我还缺少什么吗?

因为
tv
结构的
tv\u usec
成员没有初始化,它将有一个不确定的值

这个不确定的值几乎可以被视为随机或垃圾,并可能导致未定义的行为

而未定义的行为可能会像在您的案例中一样表现出来


即使不使用
tv\u usec
字段,也需要对其进行初始化,最好是将其初始化为
0
,因为未使用该字段。

因为
tv
结构的
tv\u usec
成员未初始化,因此它将具有不确定的值

这个不确定的值几乎可以被视为随机或垃圾,并可能导致未定义的行为

而未定义的行为可能会像在您的案例中一样表现出来


即使您不使用
tv\u usec
字段,也需要对其进行初始化,最好是
0
,因为它没有被使用。

您忘记了初始化
tv\u usec
结构的
成员。现在它将有一个不确定的值,这可能导致未定义的行为。是否必须同时声明这两个值?此外,
tv\u usec
必须以微秒为单位初始化为与秒相同的值。对吗?是的,你必须初始化整个结构。它可以显式地初始化为零(就像您对
tv_sec
成员所做的那样),或者通过在定义上初始化
tv
结构(如
struct timeval tv={0,0};
),初始化
tv_usec
起作用。非常感谢。您可以添加它作为答案吗?您忘记初始化
tv
结构的
tv\u usec
成员。现在它将有一个不确定的值,这可能导致未定义的行为。是否必须同时声明这两个值?此外,
tv\u usec
必须以微秒为单位初始化为与秒相同的值。对吗?是的,你必须初始化整个结构。它可以显式地初始化为零(就像您对
tv_sec
成员所做的那样),或者通过在定义上初始化
tv
结构(如
struct timeval tv={0,0};
),初始化
tv_usec
起作用。非常感谢。你能加上它作为答案吗?
include <sys/eventfd.h>
#include <unistd.h>
#include <inttypes.h>           /* Definition of PRIu64 & PRIx64 */
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>             /* Definition of uint64_t */

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
    int efd;
    uint64_t u;
    ssize_t s;
    int j;
    int retval;
    fd_set rfds;
    struct timeval tv;
    int count = 0;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    efd = eventfd(0, EFD_CLOEXEC | EFD_SEMAPHORE);
    if (efd == -1)
        handle_error("eventfd");

    switch (fork()) {
        case 0:
            for (j = 1; j < argc; j++) {
                printf("Child writing %s to efd\n", argv[j]);
                u = strtoull(argv[j], NULL, 0);
                /* strtoull() allows various bases */
                s = write(efd, &u, sizeof(uint64_t));
                if (s != sizeof(uint64_t))
                    handle_error("write");
            }
            printf("Child completed write loop\n");
            sleep(60);

            for (j = 1; j < argc; j++) {
                printf("Child writing %s to efd\n", argv[j]);
                u = strtoull(argv[j], NULL, 0);
                /* strtoull() allows various bases */
                s = write(efd, &u, sizeof(uint64_t));
                if (s != sizeof(uint64_t))
                        handle_error("write");
            }
            sleep(10);
            for (j = 1; j < 10; j++) {
                printf("Child writing %s to efd\n", argv[j]);
                u = strtoull(argv[j], NULL, 0);
                /* strtoull() allows various bases */
                s = write(efd, &u, sizeof(uint64_t));
                if (s != sizeof(uint64_t))
                        handle_error("write");
            }

            exit(EXIT_SUCCESS);

        default:
            FD_ZERO(&rfds);
            FD_SET(efd, &rfds);
            tv.tv_sec = 5;
            printf("Parent about to read\n");
            while(1) {
                count++;
                printf("entering\n");
                retval = select(efd + 1, &rfds, NULL, NULL, &tv);
                printf("THE RETVAL IS %d\n", retval);
                if (retval == -1) {
                    printf("fetched nothing\n");
                }
                else if (retval > 0) {
                    s = read(efd, &u, sizeof(uint64_t));
                    if (s != sizeof(uint64_t))
                        handle_error("read");
                printf("Parent read %"PRIu64" (%#"PRIx64") from efd\n", u, u);
                }
                printf("count...%d\n", count);
        }
        case -1:
            handle_error("fork");
    }
    return 0;
}
./a.out 10 3 4 5
event fd is 3
Parent about to read
entering
Child writing 10 to efd
Child writing 3 to efd
Child writing 4 to efd
Child writing 5 to efd
hey THE RETVAL IS 1
Child completed write loop
Parent read 1 (0x1) from efd
count...1
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...2
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...3
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...4
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...5
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...6
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...7
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...8
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...9
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...10
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...11
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...12
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...13
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...14
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...15
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...16
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...17
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...18
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...19
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...20
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...21
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...22
entering
Child writing 10 to efd
Child writing 3 to efd
Child writing 4 to efd
Child writing 5 to efd
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...23
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...24
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...25
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...26
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...27
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...28
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...29
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...30
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...31
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...32
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...33
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...34
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...35
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...36
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...37
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...38
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...39
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...40
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...41
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...42
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...43
entering
hey THE RETVAL IS 1
Parent read 1 (0x1) from efd
count...44
entering
.... upto 66