Steward
分享是一種喜悅、更是一種幸福
程式語言 - GNU - C/C++ - Event
參考資料:
https://stackoverflow.com/questions/77905421/linux-how-to-wait-on-event-without-using-mutex
main.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <poll.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/eventfd.h>
static int create_event(bool state)
{
return eventfd(state ? 1 : 0, EFD_CLOEXEC | EFD_NONBLOCK);
}
static bool reset_event(int fd)
{
uint64_t dummy = 0;
ssize_t r = read(fd, &dummy, sizeof(dummy));
if ((r < 0) && (errno != EAGAIN)) {
return false;
}
return true;
}
static bool set_event(int fd)
{
uint64_t dummy = 1;
ssize_t r = write(fd, &dummy, sizeof(dummy));
if (r < 0) {
return false;
}
return true;
}
// timeout < 0: infinite
// timeout > 0: timeout in ms
// timeout = 0: just checks if event was set
static bool wait_for_event(int fd, int timeout)
{
int rc = -1;
errno = EINTR;
struct pollfd pfd = { 0 };
do {
pfd.fd = fd;
pfd.events = POLLIN;
pfd.revents = 0;
rc = poll(&pfd, 1, timeout);
} while ((rc < 0) && (errno == EINTR));
if (rc < 0) {
return false;
}
if ((rc == 0) || !(pfd.revents & POLLIN)) {
errno = 0;
return false;
}
return true;
}
static void* mythread(void *param)
{
printf("mythread++\n");
printf("wait for 1s...\n");
usleep(1000000);
printf("set event\n");
set_event((uintptr_t)param);
printf("mythread--\n");
return NULL;
}
int main(int argc, char *argv[])
{
bool r = false;
int event = -1;
pthread_t thread_id = 0;
event = create_event(false);
pthread_create(&thread_id, NULL, mythread, (void *)(uintptr_t)event);
r = wait_for_event(event, -1);
printf("wait for event (r=%d)\n", r);
reset_event(event);
r = wait_for_event(event, 0);
printf("query event: (r=%d)\n", r);
pthread_join(thread_id, NULL);
close(event);
return 0;
}
編譯、執行
$ gcc main.c -o main
$ ./main
mythread++
wait for 1s...
set event
mythread--
wait for event (r=1)
query event: (r=0)