I want to write a go program that effectively blocks until a named pipe is ready to be read, then reads it, and blocks again. I understand that I can use a goroutine to read data from IO, and send it to the main goroutine using a channel—that makes sense to me. What I don't understand is how to consume 0 CPU while waiting for IO in the goroutine. When I call File.Read, I immediately receive an EOF, then the loop repeats causing the CPU to spike.
Here is the equivalent C code that I am trying to replicate:
# The file named "file" was created with mkfifo
# When I run `echo "hi" > file` I expect the C program to print out the characters in the file.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
int main(void) {
printf("hello world\n");
int fd = open("file", O_RDONLY);
fd_set rd, wr, er;
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&er);
FD_SET(fd, &rd);
char data[1];
for(;;) {
printf("selecting\n");
int zz = select(fd+1, &rd, &wr, &er, NULL);
printf("select returned %i\n", zz);
if (zz && FD_ISSET(fd, &rd)) {
ssize_t size = read(fd, &data, 1);
printf("read size %i\n", (int)(size));
printf("data is %s %i\n", data, data[0]);
}
}
return 1;
}
Cheers,
Sandro