加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

CreateThread包装函数

发布时间:2020-12-16 06:53:44 所属栏目:百科 来源:网络整理
导读:我目前正在开发一个项目,我们使用pthreads为UNIX系统提供C线程实现.现在我们希望能够在 Windows上运行整个项目,我正在翻译WIN32的所有线程.现在我遇到了一个问题,我无法想出一个像样的解决方案. 我有thrd_create()函数: static inline int thrd_create(thrd
我目前正在开发一个项目,我们使用pthreads为UNIX系统提供C线程实现.现在我们希望能够在 Windows上运行整个项目,我正在翻译WIN32的所有线程.现在我遇到了一个问题,我无法想出一个像样的解决方案.

我有thrd_create()函数:

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,wrapper_function,(LPVOID) args,NULL);
    if (!*thr) {
        free (args);
        return thrd_error;
    }
    return thrd_success;
}

该函数应该创建一个新线程,并且用户提供一个启动函数.为方便起见,我想保留调用thrd_create()的实现,如果可能的话.出于这个原因,我创建了一个wrapper_function:

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?用户为pthread实现提供的函数具有void返回类型,因此我不会从中获得任何结果.有什么建议?

编辑

Args看起来像这样:

struct Args {
    void (*function)(void * aArg);
    void* arg;
};
typedef struct Args Args;

解决方法

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

> Windows
> Pthreads

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

一个近似的API可能是以下几点:

/* 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);

一个近似的实现将是:

#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,_win_entry_f,t,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看起来有点像这样.

error_t func(void* args) {
  return OK;
}

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

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

显然你需要实现自己的取消,结果收集,加入……

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读