在C中,我尝试执行以下操作:
typedef struct {
int length;
int items[]; /* 1 */
} wchararray_t;
typedef struct {
long hash;
wchararray_t chars; /* 2 */
} string_t;
static string_t s1 = {
617862378,
{ 5, { 'H', 'e', 'l', 'l', 'o' } } /* 3 */
};
Run Code Online (Sandbox Code Playgroud)
总而言之,我希望一种类型string_t以另一种类型结束,该类型wchararray_t本身是动态大小的 - 其大小存储在其中length.此外,我还想写一个预建的特殊字符串,作为静态数据,这里s1长度为5.
上面的代码假定C99支持/* 1 */./* 2 */据我所知,将子结构包含在更大的结构中,即使是C99标准也不支持 - 但GCC接受它.然而,在/* 3 */GCC放弃:
error: initialization of flexible array member in a nested …Run Code Online (Sandbox Code Playgroud) 从C中的文件描述符获取文件名的问题的变体.这是关于Linux的.
如果我有一个引用常规文件的文件描述符,我可以通过给它一个新的文件名"保存"文件描述符(当然,它在同一设备上的某个地方)?我正在寻找类似于重命名(2)或链接(2)的东西,但是它会接受文件描述符作为输入而不是文件名.
重命名(2)和链接(2)的问题在于,即使您可以尝试从文件descritor转到文件名,这可能会失败.我正在更准确地考虑打开的文件描述符引用已经取消链接的文件的情况 - 在这种情况下,文件没有更多名称.当我们关闭()文件描述符时,似乎无法阻止文件被删除.但我错了吗?我们可以使用Posix甚至是Linux API再次命名吗?
更新:我们实际上可以在Linux上看到已删除文件的内容/proc/<pid>/fd/<fd>,即使它看起来像一个破损的符号链接.但是,我们不能使用link(2)或ln(1)来重新实现这样的文件,因为它认为我们正在尝试进行跨设备链接.
我正在寻找一种锁定实现,在你有两个线程不断尝试以非常高的频率释放和重新获取相同的锁的情况下,它会优雅地降级.
当然很明显,在这种情况下,两个线程并不会显着地并行进行.从理论上讲,最好的结果是通过运行整个线程1,然后是整个线程2来实现,而不需要任何切换---因为切换只会在这里产生大量开销.所以我正在寻找一种锁定实现,通过在切换之前保持相同的线程运行一段时间而不是不断切换来优雅地处理这种情况.
因为我自己很想通过"你的程序被打破,不要那样做"来回答这个问题,这里有一些理由说明为什么我们最终会遇到这种情况.
锁是一个"单一全局锁",即一个非常粗略的锁.(它是PyPy中的全局解释器锁(GIL),但问题是关于如何一般地执行它,比如说你有一个C程序.)
我们有以下情况:
经常存在争议.在这种情况下,这是预期的:锁是一个全局锁,需要获取大多数线程才能进行.所以我们希望他们中的很大一部分都在等待锁定.这些线程中只有一个可以进展.
持有锁的线程有时会爆发短暂的释放.一个典型的例子是,如果这个线程重复调用"外部的东西",例如对文件的许多短写.这些写入中的每一个通常都很快完成.锁定仍然必须被释放,以防这个外部事件花费比预期更长的时间(例如,如果写入实际上需要等待磁盘I/O),以便在这种情况下另一个线程可以获取锁定.
如果我们使用一些标准互斥锁进行锁定,那么一旦所有者释放锁定,锁定通常会切换到另一个线程.但问题是,如果程序运行多个线程,每个线程都想要做一个长期的短期发布.该程序最终花费大部分时间在CPU之间切换锁定.
在切换之前运行相同的线程一段时间要快得多,至少只要锁被释放很短的时间.(例如在Linux/pthread上,即使有其他等待线程,有时会立即重新获取锁定,但是我们在大多数情况下都会喜欢这种结果,而不仅仅是有时.)
当然,一旦锁被释放更长的时间,那么将锁的所有权转移到另一个线程就成了一个好主意.
所以我正在寻找关于如何做到这一点的一般想法.我想它应该存在于某个地方---在一篇论文中,还是在一些多线程库中?
作为参考,PyPy试图通过轮询来实现这样的东西:锁只是一个全局变量,具有同步的比较和交换但没有OS调用; 其中一个等待线程被赋予"窃取者"的角色; "stealer"线程每100微秒唤醒一次以检查变量.这并不是非常糟糕(除了正在运行的线程消耗的100%之外,它的成本可能是CPU时间的1-2%).这实际上实现了我在这里要求的东西,但问题是这是一个不干净地支持更传统的锁的情况的hack:例如,如果线程1试图向线程2发送消息并等待回答,两个线程切换每个平均需要100微秒 - 如果快速处理消息,则太多了.