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