【问题标题】:Why makecontext's func only accepts integer arguments为什么makecontext的函数只接受整数参数
【发布时间】:2017-08-11 04:43:43
【问题描述】:

makecontext 的手册页指出 argc 之后的参数只能是整数(int):

...函数 func 被调用,并传递了 argc 后面的一系列整数 (int) 参数

如果我们查看pthread_createclone 系统调用,它们有一个void* 参数要传递给func,并且struct 的指针可以包含用户希望拥有的任意数量的数据,并且这两个函数也不需要使用 va_args 。所以我的问题是为什么makecontext 不使用这种技术,即使用 void 指针,而不是 argc 和 va_args?

【问题讨论】:

    标签: c linux posix


    【解决方案1】:

    这是导致makecontext 消亡/删除的设计缺陷。请参阅包含在其中的 POSIX 的最新版本的合理文本:

    http://pubs.opengroup.org/onlinepubs/009695399/functions/makecontext.html

    随着 ISO/IEC 9899:1999 标准并入本规范,发现 ISO C 标准(子条款 6.11.6)指定使用带空括号的函数声明符已过时。因此,使用函数原型:

    void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
    

    正在使用 ISO C 标准的过时功能。因此,严格遵守 POSIX 应用程序不能使用这种形式。因此,getcontext()、makecontext() 和 swapcontext() 的使用被标记为过时。

    在 ISO C 标准中没有办法指定一个非过时的函数原型,指示一个函数将使用任意数量(包括零)的任意类型的参数(包括整数、指向数据的指针、指向函数和复合类型)。

    用许多处理各种数量和类型的参数的 ISO C 标准兼容函数替换 makecontext() 将迫使 makecontext() 的所有现有用法都被重写,几乎没有收益。现在很少有应用程序使用 *context() 例程。那些确实使用它们的人几乎总是使用它们来实现协同程序。通过维护 makecontext() 的 XSH 第 5 版规范,现有应用程序将继续工作,尽管它们不能被归类为严格符合标准的应用程序。

    在 ISO C 标准中(不使用过时的行为)无法指定标准功能,严格遵守 XSH 第 5 版规范中使用 ISO C 标准的行为。线程可用于实现 makecontext()、getcontext() 和 swapcontext() 提供的功能,但使用起来更复杂。人们认为,发明新的 ISO C 标准兼容接口来描述可以用 XSH 完成的功能,第 5 期函数,然后将应用程序转换为使用它们会比仅仅将使用它们的应用程序转换为使用线程造成更多的困难。

    请注意,为了让makecontext 的实现真正调用func,它必须知道如何设置一个堆栈帧以使用正确数量和类型的参数进入函数。如果要求所有参数具有相同的类型 (int),则可以仅从数字 argc 中知道这一点。如果允许它们具有不同的类型,调用者将不得不以某种方式将类型规范作为参数传递给makecontext;一个简单的计数不足以知道如何将它们从makecontext 收到的va_list 复制到堆栈帧以进入func

    当然makecontextfunc 应该只取一个void *,那么问题就不会出现了。但它没有。

    【讨论】:

    • 嗯,这是否意味着 makecontext 和功能现在已过时且不应使用?这些上下文函数是否有任何符合标准的替换?
    • @fluter:线程(请参阅我引用的文本末尾)是符合标准的替换 makecontext 等的预期用途。您可以执行相同类型的“协作线程”可实现通过使用条件变量与它们一起使用真实线程。对于这些功能的更多奥术/黑客应用程序(无论如何都没有真正定义好),没有真正的替代品。
    猜你喜欢
    • 2015-08-21
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 2014-12-06
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    相关资源
    最近更新 更多