c++ - Port program that uses CreateEvent and WaitForMultipleObjects to Linux -
i need port multiprocess application uses windows api functions setevent
, createevent
, waitformultipleobjects
linux. have found many threads concerning issue, none of them provided reasonable solution problem.
i have application forks 3 processes , manages thread workerpool of 1 process via these events.
i had multiple solutions issue. 1 create fifo special files on linux using mkfifo
on linux , use select statement awaken threads. problem solution operate differently waitformultipleobjects
. example if 10 threads of workerpool wait event , call setevent
5 times, 5 workerthreads wake , work, when using fifo variant in linux, wake every thread, in select statement , waiting data put in fifo. best way describe windows api kind of works global semaphore count of one.
i thought using pthreads
, condition variables
recreate , share variables via shared memory (shm_open
, mmap
), run same issue here!
what reasonable way recreate behaviour on linux? found solutions doing inside of single process, doing between multiple processes?
any ideas appreciated (note: not expect full implementation, need more ideas myself started problem).
you use semaphore (sem_init
), work on shared memory. there's named semaphores (sem_open
) if want initialize them different processes. if need exchange messages workers, e.g. pass actual tasks them, 1 way resolve use posix message queues. named , work inter-process. here's short example. note first worker thread initializes message queue, others use attributes of existing one. also, (might) remain(s) persistent until explicitly removed using mq_unlink
, skipped here simplicity.
receiver worker threads:
// link -lrt -pthread #include <fcntl.h> #include <mqueue.h> #include <pthread.h> #include <stdio.h> #include <unistd.h> void *receiver_thread(void *param) { struct mq_attr mq_attrs = { 0, 10, 254, 0 }; mqd_t mq = mq_open("/myqueue", o_rdonly | o_creat, 00644, &mq_attrs); if(mq < 0) { perror("mq_open"); return null; } char msg_buf[255]; unsigned prio; while(1) { ssize_t msg_len = mq_receive(mq, msg_buf, sizeof(msg_buf), &prio); if(msg_len < 0) { perror("mq_receive"); break; } msg_buf[msg_len] = 0; printf("[%lu] received: %s\n", pthread_self(), msg_buf); sleep(2); } } int main() { pthread_t workers[5]; for(int i=0; i<5; i++) { pthread_create(&workers[i], null, &receiver_thread, null); } getchar(); }
sender:
#include <fcntl.h> #include <stdio.h> #include <mqueue.h> #include <unistd.h> int main() { mqd_t mq = mq_open("/myqueue", o_wronly); if(mq < 0) { perror("mq_open"); } char msg_buf[255]; unsigned prio; for(int i=0; i<255; i++) { int msg_len = sprintf(msg_buf, "message #%d", i); mq_send(mq, msg_buf, msg_len, 0); sleep(1); } }
Comments
Post a Comment