什么是异步返回尚未完全“设置”(或处理)的结果(作为结构)的最佳方法

好吧,老实说,我试过查找“C中的异步函数”(结果仅供C#使用),但我没有得到任何关于C.所以我会在这里问它,但是如果在StackExchange上有更好的,已经问过的问题或者你有什么,请指导我.

所以我正在教自己关于并发和异步函数以及所有这些,所以我试图创建自己的线程池.到目前为止,我还处于计划阶段,我正在努力寻找一条明确的旅行路径,但是我不想要提供代码,我只想在正确的方向上轻推一下(否则练习毫无意义).

从一个没有“准备好”的函数异步返回的最佳方法是什么?在那里,它几乎立即返回,即使它当前正在处理用户给出的任务. “任务”将是一个回调和参数,以适应所需的必要pthread_t参数,虽然我稍后会处理属性.该函数返回一个名为“Result”的结构,它包含void *返回值和一个名为“ready”的字节(unsigned char),它将保存值0和1.因此,当“Result”不是“ready”时,则该用户不应该尝试处理该项目.然后,如果用户返回NULL,则“item”可以为NULL,但“ready”允许用户知道它已完成.

struct Result {
    /// Determines whether or not it has been processed.
    unsigned char ready;
    /// The return type, NULL until ready.
    void *item;
};

结构并不是真的完整,但它是体现我正在尝试做的事情的基本原型.这不是真正的问题,尽管让我知道它是否是错误的方法.

接下来我必须实际处理这个东西,而不是阻塞,直到一切都完成.正如我所说,该函数将创建Result,然后异步处理它并立即返回(通过返回此结果).问题是异步处理.我想在thread_pool中产生另一个线程,但我觉得它缺少线程池的重点,因为它不再保持简单.

 这就是我的想法(我感觉非常过于复杂).在函数add_task中,使用传递的sub_process结构生成一个新线程(线程A),然后返回未处理但初始化的结果.在生成的线程中,它还会使用原始回调和参数生成另一个线程(请参阅问题?这是线程B),将线程A与线程B连接以捕获它的返回值,然后将其存储在结果的项目成员中.由于结果将指向用户持有的完全相同的结构,因此它应该不是问题.

我的问题是它产生了2个线程,而不是能够在1中完成它,所以我想知道我是否做错了,使事情变得复杂.有没有更好的方法来做到这一点? pthread的库是否具有异步为我执行此操作的功能?无论如何,原型Sub_Process结构如下.

/// Makes it easier than having to retype everything.
typedef void *(*thread_callback)(void *args);

struct Sub_Process {
    /// Result to be processed.
    Result *result;
    /// Thread callback to be processed
    thread_callback cb;
    /// Arguments to be passed to the callback
    void *args;
};

我做错了吗?我有一种感觉,我错过了Thread_Pool的全部内容.另一个问题是,有没有办法产生一个创建的线程,但等待而不做任何事情?我想通过创建所有线程来处理它,让它们只是在处理函数中等待直到被调用,但我觉得这是错误的方法.

为了进一步阐述,我还将发布一些我正在尝试here的伪代码

注意:建议我在这里发布这个问题以获得答案,所以它已被复制并粘贴,知道是否有任何错误的编辑.

编辑:不再生成另一个线程,而是直接调用回调,因此另一个线程的额外开销应该不是问题.

最佳答案 我认为你的意图是,一个线程将请求执行异步工作,然后继续执行一些不同的工作,直到它需要异步操作的结果才能继续.

在这种情况下,您需要一种方法让请求线程停止并等待结果准备就绪.您可以通过在Result中嵌入互斥和条件变量对来完成此操作:

struct Result {
    /// Lock to protect contents of `Result`
    pthread_mutex_t lock;
    /// Condition variable to signal result being ready
    pthread_cond_t cond;
    /// Determines whether or not it has been processed.
    unsigned char ready;
    /// The return type, NULL until ready.
    void *item;
};

当请求线程到达需要异步结果的点时,它使用条件变量:

pthread_mutex_lock(&result->lock);
while (!result->ready)
    pthread_cond_wait(&result->cond, &result->lock);
pthread_mutex_unlock(&result->lock);

您可以将此包装在等待结果可用的函数内,销毁互斥锁​​和条件变量,释放Result结构并返回返回值.

处理完成后线程池线程中的相应代码将是:

pthread_mutex_lock(&result->lock);
result->item = item;
result->ready = 1;
pthread_cond_signal(&result->cond);
pthread_mutex_unlock(&result->lock);

Another question is, is there a way to spawn a thread that is created,
but waiting and not doing anything? I was thinking of handling this by
creating all of the threads by having them just wait in a processing
function until called, but I’ve a feeling this is the wrong way to go
about this.

不,你在这里走在正确的轨道上.让线程池线程等待一些工作可用的机制与上述条件变量相同.

点赞