目前,我尝试在集群系统中实现共享堆栈。该系统有两个地址空间,一个是私有的,在所有处理器之间共享。
如何在c编程中更改堆栈的开头和结尾?
即,我想将堆栈放在共享空间中并更改程序流程以使用它。
答案 0 :(得分:1)
我的建议是:不惜一切代价远离指向基于堆栈的对象的指针。如果你这样做,你将要求发送线程永远不会从创建共享对象的函数返回,然后才能 proove ,任何其他线程都不再以任何方式访问该对象。这是a)接下来是不可能的,并且b)需要性能杀死锁定。未能正确执行此操作的后果将完全是不确定的错误!不要这样做!
我建议malloc 所有对象离开一个线程的上下文并使用线程安全引用计数。您还可以查看线程安全的共享数据结构,如队列,双链表等。
答案 1 :(得分:1)
我怀疑你能在C中很好地实现你想要的东西(除非你想改变编译器)。
你说你想要OpenMP风格的编程。这相当于一个顶级线程,它可以分叉子进程来操作父进程提供的共享空间。 Fancy OpenMP以递归方式执行此操作。
要做到这一点很好,你的系统/工具/编译器需要能够识别
* threads of computations
* what variables are declared by each thread
* what variables (or parts thereof) are offered by a thread to its thread children
如果你可以做这些事情(并且通过显式语言支持更容易,OpenMP pragma在这个过程中帮助启用OpenMP的编译器),那么你可以将线程的数据分成3个部分:
1. storage accessed only by the thread, and not by its children
2. storage declared by the thread, but accessed only by individual children (e.g., slices of arrays)
3. storage read and written by the parent thread and its children
此时,您可以考虑为线程布局“局部变量”,从而叠加空间。 线程本地存储仅分配给父线程的堆栈空间。父声明但子处理的存储空间成为分配给子节点的本地空间/堆栈的空间。所有人都可以读取和写入存储,可以放在任何可以访问的地方(在父线程的本地空间,堆栈中,堆存储中),并且需要访问保护以防止数据争用。 [你不能强迫传统的C编译器为你做这件事。]
将数据划分到不同的线程本地/堆栈空间使得您在共享内存中使用C并将“所有线程堆栈”设置为一个位置的明显方案难以利用。如果所有线程具有相同的堆栈区域,哪个存储对于线程是本地的?特别是,如果两个线程都想要写入自己的局部变量I,并且我在共享空间中,那么它实际上并不是本地的。如果将共享空间划分为不相交的线程堆栈,那么您实际上并没有共享存储,至少不是按名称共享;充其量你可以使用指针分享到其他线程堆栈。所有这些都很难编程,因此容易出错,我不想调试为这样的系统编写的程序。它还对您宝贵的共享空间提出了额外的要求;你有线程局部变量吃它,但不需要共享。
如果你有一个静态的线程数,并继续坚持使用一些可用的C编译器,那么最好手动分配共享数据(在运行时动态分配,或者在编码/编译时通过分区分配)共享内存)。但是你的线程现在可以在其本地存储器中以“标准”堆栈运行,并且不需要堆栈切换。
[编辑:在我对仙人掌堆栈发表评论后,OP希望了解更多信息。我包括在内 这里的评论,以及关于它们的细节的一些指示]
堆栈可以由多个线程共享。 cactus stack 的概念是一个父线程,它具有一个现有的(cactus)堆栈,与其所有并行子进程共享,每个子进程都有自己的堆栈空间,但可以看到/分享父母的堆栈。
我们的PARLANSE并行编程语言直接实现了这个概念,我们在大约2-4百万行代码的应用程序中使用它。每个函数调用heap-allocation 它的激活记录(使用线程本地分配器来提高速度),并通过词法级别向上寻址访问所有父堆栈段,实现为父项在函数调用中传递给其子项的一组指针。下面的英特尔博客准确描述了我们这样做的原因。
参考文献:
答案 2 :(得分:-1)
为了清晰起见,让我编辑一下:
您只是想改变STACK的含义和定义。 STACK by Today的定义只能由一个线程用于实际的STACK操作。进程或线程可以共享STACK以使用普通内存。在这种情况下,你真的应该把那块内存称为“共享内存”而不是“共享堆栈”。您真正想在集群环境中做什么或实现什么?
以下是无法共享STACK的示例...
Thread-1函数调用序列:
main()
thr1_f1()
thr1_f2()
thr1_f3()
thr1_f4()
Thread-2函数调用序列:
main()
thr2_f1()
thr2_f2()
thr2_f3()
thr2_f4()
假设这些线程正在共享STACK。这是一个可能的函数调用序列......