将 void*(*)(void*) 类型转换为 void(*)(void)

2023-12-29

作为作业的一部分,我试图创建一个像 pthreads 这样的用户级线程库。

为了处理线程之间的上下文切换,我使用“swapcontext”函数。在使用它之前,我必须使用“makecontext”函数创建一个上下文。 “makecontext”需要一个具有返回类型的函数指针void和参数类型(void).

然而,线程函数必须是以下类型void* thread_func (void*)

有没有办法进行类型转换?或者还有其他方法可以在用户级别进行上下文切换吗?


通过将函数的地址转换为不同的原型并通过结果指针调用它来调用具有不兼容原型的函数是非法的:

void *my_callback(void *arg) { ... }

void (*broken)(void *) = (void (*)(void *)) my_callback;
broken(some_arg);   // incorrect, my_callback returns a `void *`

你能做的就是传递给makecontext您自己的回调将调用thread_func并忽略它的返回值。仅用于调用另一个函数的小函数有时称为蹦床 http://en.wikipedia.org/wiki/Trampoline_%28computing%29.

/* return type is compatible with the prototype of the callback received
   by makecontext; simply calls the real callback */
static void trampoline(int cb, int arg)
{
  void *(*real_cb)(void *) = (void *(*)(void *)) cb;
  void *real_arg = arg;
  real_cb(real_arg);
}

int my_pthread_create(void *(*cb)(void *), void *arg)
{
  ucontext_t *ucp;
  ...
  /* For brevity treating `void *` as the same size as `int` -
     DO NOT USE AS-IS.
     makecontext exposes an annoyingly inconvenient API that only
     accepts int arguments; correct code would deconstruct each
     pointer into two ints (on architectures where pointer is
     larger than int) and reconstruct them in the trampoline. */
  makecontext(ucp, trampoline, 2, (int) cb, (int) arg);
  ...
}

为了获得奖励积分,您可以修改蹦床以存储void *回调函数返回的值在堆栈上,并且具有相当于pthread_join()检索它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 void*(*)(void*) 类型转换为 void(*)(void) 的相关文章

随机推荐

  • 获取插入行的ID cassandra .Net

    我正在使用 datastax C 驱动程序将一行插入 cassandra 数据库 我的示例代码如下所示 var cluster Cluster Builder AddContactPoints localhost Build using c
  • 仅将 css 样式设置为表格的第一行

    如何用CSS访问不同表的第一行tr班级名称 div table tbody tr class head td Date td td Info td td More td tr tr td td tr tbody table div 如何制作
  • 使用 animate 中的 Step 函数来变换旋转元素

    All 我正在尝试使用 jquery animate 和 css 转换属性创建 往返 动画 我提到this https stackoverflow com questions 5462275 animate element transfor
  • 过滤掉 Log4j2 文件中的 Hibernate 日志

    我有一个log4j2 xml文件如下 它正在工作 但它获取了大量 Hibernate 和 GWT 日志文件 如何排除这些包 或者如何让我的日志文件仅包含包层次结构中的日志记录
  • 尝试使用 ssh2_auth_pubkey_file() 连接

    我正在尝试制作一个在终端上运行的 php 脚本 该脚本将通过 ssh 连接到远程服务器并检索文件 这是我到目前为止的代码 usr bin php q
  • 多视图控件如何处理其视图状态?

    多视图控件是否包含其每个视图的视图状态信息 无论视图当前是否可见 是的 所有视图仍然存在 只是不活动的视图被隐藏 禁用 http msdn microsoft com en us library system web ui webcontr
  • 使用 PayPal API 通过交易 ID 获取付款

    我有 PayPal 交易 ID 但不知道与其关联的付款 ID 付款不一定是由 REST API 创建的 我想使用交易ID查询付款 REST API 文档建议通过交易 ID 查找销售额仅当使用 REST API 创建时才可能 https de
  • 一次处理 N 个作业的 Asyncio Worker?

    我正在尝试做一个asyncio工人类将消耗作业队列中的作业并处理最多N并行工作 某些作业可能会排队其他作业 当作业队列为空并且工作线程完成所有当前作业时 它应该结束 我还在挣扎asyncio从概念上讲 这是我的尝试之一 其中N 3 impo
  • Jquery .remove() 撤消?

    有什么办法可以实现这一点吗 我正在使用一个分页插件 它读取 ul 中的 li 数量 并确定要吐出的编号链接的数量 您可能想使用 hide 并检查 li 是否可见 这可以通过以下方式完成 li visible
  • PySpark - 获取组中每行的行号

    使用 pyspark 我希望能够对 Spark 数据帧进行分组 对组进行排序 然后提供行号 所以 Group Date A 2000 A 2002 A 2007 B 1999 B 2015 会成为 Group Date row num A
  • JaCoCo 和 Gradle - 过滤选项

    我目前正在使用 Gradle 插件来运行 JaCoCo 来进行代码覆盖率报告 我想在我的 build gradle 中指定一些过滤选项 https github com jacoco jacoco wiki FilteringOptions
  • 如何使用 openpyxl“格式化单元格”?

    我想使用 openpyxl 格式化 Excel 工作表中的列单元格 使其数字小数位为 0 示例表 B C 63245634566 NAME 63562341234 NAME 23452345345 NAME 21345234554 NAME
  • Jetpack Compose 矢量解析问题

    我正在尝试加载向量 但不断收到此错误堆栈跟踪 java lang IllegalArgumentException Unknown command for R at androidx compose ui graphics vector P
  • 如何在 TCL 中创建并迭代哈希值的哈希值?

    如何在 TCL 中创建并迭代哈希值的哈希值 如果我有这样的数据 foo a gt aa gt aa1 aa2 aa3 ab gt ab1 ab2 ab3 ac gt ac1 ac2 ac3 b gt ba gt ba1 ba2 ba3 bb
  • 带计时器的自动静音 Android 设备设置我的用户

    我的应用程序中有 2 个按钮 开始时间和结束时间 现在我希望设备在用户设置的开始和结束持续时间内进入静音模式 我该怎么做 我的用于获取开始时间和结束时间输入的代码mainactivity java code包 com example h m
  • 在C中通过名称获取进程ID

    我试图通过进程名称获取进程 ID 例如 notepad exe 但之前 Stack Overflow 上的解决方案似乎无法正常工作 这是我尝试过的 DWORD FindProcessId const char processname HAN
  • Sencha touch 2 + Apple 推送通知 + Ext.device.Push

    我最近开始使用 Sencha Touch 2 进行开发 目前我正在创建一个需要 Apple 推送通知支持的应用程序 因此 我在 Apple 开发人员中心创建了必要的证书 并使用它们将应用程序与 Sencha Touch SDK 工具打包在一
  • XML 1.0 和 XML 2.0 之间的区别

    XML 1 0 和 XML 2 0 有什么区别 XML 2 0 从来没有出现过 即使是草案也是如此 有一个并不完全流行的 XML 1 1 标准 它有三个主要变化 其中最重要的变化是在 XML 1 0 第五版中就地应用于 XML 1 0 这一
  • 如何计算 3d numpy 数组中的凸包图像/体积

    我想知道是否有任何基于 numpy 的工具可以 给定 3D 二进制输入 numpy 图像 找到其凸包 并返回此 3D 凸包内的索引或类似体素 3D 像素 列表 一种可能性是使用skimage morphology convex hull i
  • 将 void*(*)(void*) 类型转换为 void(*)(void)

    作为作业的一部分 我试图创建一个像 pthreads 这样的用户级线程库 为了处理线程之间的上下文切换 我使用 swapcontext 函数 在使用它之前 我必须使用 makecontext 函数创建一个上下文 makecontext 需要