c-使用CreateEvent和WaitForMultipleObjects的端口程序到Linux

我需要将使用Windows API函数SetEvent,CreateEvent和WaitForMultipleObjects的多进程应用程序移植到Linux.我发现了许多与此问题有关的线程,但是没有一个线程为我的问题提供了合理的解决方案.

我有一个应用程序,它可以分为三个进程,并通过这些事件管理一个进程的线程工作池.

我对此问题有多种解决方案.一种是在Linux上使用mkfifo在FIFO上创建FIFO特殊文件,然后使用select语句唤醒线程.问题在于该解决方案的运行方式与WaitForMultipleObjects不同.例如,如果工作池中有10个线程将等待事件,而我调用SetEvent五次,则恰好五个工作线程将被唤醒并完成工作,在Linux中使用FIFO变体时,它将唤醒每个线程,即我在选择中语句并等待将数据放入fifo.描述此问题的最佳方法是Windows API的工作方式类似于一个计数为1的全局信号量.

我还考虑过使用pthreads和条件变量来重新创建它并通过共享内存(shm_open和mmap)共享变量,但是我在这里遇到了同样的问题!

在Linux上重新创建此行为的合理方法是什么?我发现有一些解决方案可以在单个流程中执行此操作,但是在多个流程之间执行此操作又如何呢?

任何想法都会受到赞赏(注意:我不希望有完整的实现,我只需要更多想法就可以开始解决此问题).

解决方法:

您可以使用信号量(sem_init),它们在共享内存上工作.如果您要从不同的进程初始化信号量,则也将其命名为(sem_open).如果您需要与员工交流信息,例如将实际任务传递给他们,那么解决此问题的一种方法是使用POSIX message queues.它们被命名并在进程间工作.这是一个简短的例子.请注意,只有第一个工作线程实际上会初始化消息队列,其他工作线程使用现有线程的属性.而且,它可能会保持持久,直到使用mq_unlink明确将其删除为止,为简单起见,在此将其跳过.

具有工作线程的接收器:

// Link with -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();
}

发件人:

#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);
    }
}
上一篇:android-如何捕获由WindowManager添加的视图中的按键


下一篇:java-业务事件框架