首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CreateThread包装函数

CreateThread包装函数
EN

Stack Overflow用户
提问于 2017-06-27 07:28:29
回答 1查看 607关注 0票数 4

我目前正在进行一个项目,在这个项目中,我们为UNIX系统提供了一个C线程实现,使用的是p线程。现在我们也希望能够在Windows上运行整个项目,我正在翻译WIN32的所有线程。现在我遇到了一个问题,我想不出一个像样的解决办法。

我有thrd_create()函数:

代码语言:javascript
复制
static inline int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
    Args* args = malloc(sizeof(Args));
    args->arg = arg;
    args->function = func;
    *thr = CreateThread(NULL, 0, wrapper_function, (LPVOID) args, 0, NULL);
    if (!*thr) {
        free (args);
        return thrd_error;
    }
    return thrd_success;
}

这个函数应该创建一个新线程,并且用户提供了一个开始函数。为了方便起见,如果可能的话,我想保留调用thrd_create()的实现。因此,我创建了一个wrapper_function

代码语言:javascript
复制
static inline DWORD wrapper_function(LPVOID arg) {
    Args * args;
    args = (Args*) arg;
    DWORD res = args->function(args->arg); //This does obviously not work
    return res;
}

我的问题是:我的包装器函数应该返回什么DWORD?用户为p线程实现提供的函数具有空返回类型,因此我不会从中得到任何结果。有什么建议吗?

编辑

Args看起来像这样:

代码语言:javascript
复制
struct Args {
    void (*function)(void * aArg);
    void* arg;
};
typedef struct Args Args;
EN

回答 1

Stack Overflow用户

发布于 2017-06-27 12:47:40

根据手册,最好坚持正确的签名并使用返回值:

  1. 视窗
  2. 丝线

另一个值得关注的问题是args的生命周期,我认为最好的方法是调用者清理,所以需要使用线程跟踪它们,直到它终止为止。

近似的API可以大致如下所示:

代码语言:javascript
复制
/* Your general error codes enumeration
 * which should probably reside in a general
 * header 
 */
typedef enum {
  OK = 0,
  // Your application specific error codes
} error_t;

#ifdef _WIN32
  #include <Windows.h>
  typedef HANDLE thread_handle_t;
#else // assume pthreads
  #include <pthread.h>
  typedef pthread_t thread_handle_t;
#endif

typedef error_t(*entry_func_t)(void*);

typedef struct {
  entry_func_t     func;
  void             *args;
  error_t          _result;
  thread_handle_t  _handle;
} thread_t;

// returns OK(0) on success
// returns error code indicating a problem
error_t thread_create(thread_t *t);

一项近似的执行是:

代码语言:javascript
复制
#ifdef _WIN32
  DWORD _win_entry_f(void *args) {
    thread_t *t = args;
    t->_result = t->func(t->args);
    return 0; // Or some other Windows-specific value
  }

  error_t thread_create(thread_t *t) {
    error_t err = OK;
    if(!(t->_handle = ThreadCreate(NULL, 0, _win_entry_f, t, 0, NULL))) {
      switch (GetLastError()) {
        // Populate error with code
      }
    }
    return err;
  }
#else
  void * _pthread_entry_f(void *args) {
    thread_t *t = args;
    t->_result = t->func(t->args);
    return NULL; // Or some other pthreads specific value
  }

  error_t thread_create(thread_t *t, entry_func_t func, void *args) {
    error_t err = OK;
    switch(pthread_create(&t->_handle, NULL, _pthread_entry_f, t)) {
    case 0: break;
    // other cases populate err
    }
    return err;
  }
#endif

Invokation看起来有点像这样。

代码语言:javascript
复制
error_t func(void* args) {
  return OK;
}

.....................

thread_t t = { .func = func, .args = NULL };
thread_create(&t);

显然,您需要实现自己的取消、结果收集、连接、.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44774535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档