Я генерирую «события» в одном потоке и отправляю их обратно в основной поток через несколько секунд. Естественно, это не работает правильно. У меня есть два вопроса:Создание структур с одним потоком и получение в другом потоке с селектором
- Почему я получаю сообщения, полученные от bazillion в моем цикле выбора? Нужно ли мне читать из трубы, поэтому дескриптор файла больше не говорит, что там есть вещи?
- Как я могу получить ссылку на структуру из трубы?
Желаемая Выход:
$ ...
Writing event 1 to pipe
Received event on pipe
Writing event 2 to pipe
Received event on pipe
Acutal Выход:
$ ...
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event on pipe
Received event o^C
команда GCC:
gcc -o test test.c
test.c:
/* Simple example with two threads and a pipe. One thread writes structs to a
pipe every few seconds; the other reads the structs, prints out their info
and then frees the structs
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/select.h>
void mywait(int timeInSec);
// The events
typedef struct event {
int id;
int data;
} event_t;
int id = 0;
int pipefd[2];
void* pump(void *arg) { // Generates events
for (;;)
{
mywait(1); // sleep thread
printf("writing event #%i to pipe\n", id);
// generate event
event_t *event;
event = malloc(sizeof(*event));
memset(event, 0, sizeof(*event));
event->id = id++;
// write event to pipe
write(pipefd[1], &event, sizeof(event));
// NOTE: Free event in other thread
}
}
int main (int argc, char **argv)
{
printf("Starting pipe_test.c\n");
// 1. Create a pipe
pipe(pipefd);
// 2. Create thread to pump events into pipe
pthread_t tid;
if (pthread_create(&tid, NULL, pump, NULL) != 0) {
perror("pthread_create:pump");
exit(-1);
}
// 3. Set up selector in main thread to read events off pipe
int z;
fd_set readfds; //readable file descriptor
int selectmax;
selectmax = pipefd[0] + 1;
for (;;)
{
// Initialize selector
FD_ZERO(&readfds);
FD_SET(pipefd[0], &readfds);
z = select(selectmax, &readfds, NULL, NULL, NULL);
if(z < 0) {
printf("select() failed\n");
// close(pipefd); //???
return 1;
} else {
if(FD_ISSET(pipefd[0], &readfds)) {
printf("Received event on pipe\n"); // I get a shitton of these
// Get the pointer to the event struct from the pipe
// TODO: GOOD WAY TO DO THIS?
// Free the struct
// TODO
}
}
}
return 0;
}
// From http://somethingswhichidintknow.blogspot.com/2009/09/sleep-in-pthread.html
pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
void mywait(int timeInSec)
{
struct timespec timeToWait;
struct timeval now;
int rt;
gettimeofday(&now,NULL);
timeToWait.tv_sec = now.tv_sec + timeInSec;
timeToWait.tv_nsec = now.tv_usec*1000;
pthread_mutex_lock(&fakeMutex);
rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
pthread_mutex_unlock(&fakeMutex);
}
+1 только для «Естественно, это не работает правильно» :) –