我是linux和linux线程的新手.我花了一些时间谷歌搜索试图理解可用于线程同步的所有函数之间的差异.我还有一些问题.
我找到了所有这些不同类型的同步,每个同步都有许多锁定,解锁,测试锁等功能.
信号量是进程范围的,涉及文件系统(实际上我假设),并且可能是最慢的.
Futexes可能是互斥锁,自旋锁,seqlocks和rculocks使用的基本锁定机制.Futexes可能比基于它们的锁定机制更快.
自旋锁不会阻塞,从而避免上下文波动.然而,它们避免了上下文切换,代价是消耗CPU上的所有循环,直到释放锁定(旋转).出于显而易见的原因,它们应仅应用于多处理器系统.永远不要睡在螺旋锁中.
如果作者更改了工作所基于的数据,seq锁只会告诉您何时完成工作.在这种情况下,您必须返回并重复工作.
原子操作是最快的同步调用,并且可能在所有上述锁定机制中使用.您不希望对共享数据中的所有字段使用原子操作.当您访问多个数据字段时,您希望在锁定标志上使用锁(互斥锁,futex,旋转,seq,rcu)或单个原子操作.
到目前为止我对我的假设是否正确?
有谁知道各种选项的cpu周期成本? 我正在为应用添加并行性,因此我们可以获得更好的响应时间,但每个盒子运行的应用实例更少.表演是最重要的考虑因素.我不想使用上下文切换,旋转或许多额外的CPU周期来读取和写入共享内存.我绝对关心消耗的cpu周期数.
哪个(如果有的话)锁可以防止调度程序中断线程或中断...或者我只是一个白痴,所有同步机制都会这样做.什么样的中断被阻止?我可以阻止锁定线程的CPU上的所有线程或线程吗? 这个问题源于我担心中断一个线程,该线程持有一个非常常用的函数.我希望调度程序可能会调度任何可能会遇到此函数的其他工作者,然后因为它被锁定而阻塞.在带有锁的线程被重新安排并完成之前,将浪费大量上下文切换.我可以重新编写这个函数以最小化锁定时间,但它通常被称为我想使用锁来防止中断...跨所有处理器.
我正在编写用户代码...所以我得到软件中断,而不是硬件中断......对吗?我应该远离任何带有"irq"字样的功能(旋转/ seq锁).
哪些锁用于编写内核或驱动程序代码,哪些用于用户模式?
有没有人认为使用原子操作让多个线程通过链表移动是疯了? 我想通过原子方式将当前项指针更改为列表中的下一个项.如果尝试有效,则线程可以安全地使用当前项在移动之前指向的数据.现在,其他线程将沿列表移动.
futexes的?有没有理由使用它们而不是互斥体?
当没有工作时,是否有比使用条件睡眠线程更好的方法?
当使用gcc原子操作,特别是test_and_set时,我可以通过先进行非原子测试然后使用test_and_set来确认来提高性能吗? 我知道这将是特定于案例的,所以情况就是如此.有数以千计的工作项目.每个工作项都有一个初始化为0的标志.当一个线程具有对工作项的独占访问权时,该标志将为1.会有很多工作线程.一旦线程正在寻找工作,他们就可以非原子地测试1.如果他们读取1,我们肯定知道工作不可用.如果他们读零,他们需要执行原子test_and_set来确认.因此,如果原子test_and_set是500个cpu周期,因为它禁用流水线操作,导致cpu通信和L2缓存刷新/填充....并且一个简单的测试是1个周期....然后只要我有一个更好的比率当它磕磕绊绊已经完成的工作项目时,500比1 ......这将是一场胜利.
我希望使用互斥锁或自旋锁来保护代码段,我希望一次只能访问SYSTEM(而不是CPU)上的一个线程.我希望谨慎地使用gcc原子操作来选择工作并尽量减少互斥锁和自旋锁的使用.例如:可以检查工作项中的标志以查看线程是否已经工作(0 =否,1 =是或正在进行中).一个简单的test_and_set告诉线程它是否有效或需要继续.我希望在工作时使用条件唤醒线程.
谢谢!
我试图将整个文件读入变量而不删除任何字符.我敢肯定这一定很简单.
这不起作用,因为它删除了重复空格,所有标签和换行符:
$ echo 'fred wilma' > somefile; z=$(cat somefile); echo $z
fred wilma
Run Code Online (Sandbox Code Playgroud)
我可以通过简单的赋值看到相同的过滤,如下所示:
$ z='fred wilma'; echo $z
fred wilma
Run Code Online (Sandbox Code Playgroud)
但不是我这样做的时候:
$ echo 'fred wilma'
fred wilma
Run Code Online (Sandbox Code Playgroud)
如何获取bash变量以在分配时停止解析和过滤?
struct stat中的一个字段是st_mtime.我认为这是自1970年1月1日以来的秒数.那是GMT还是当地时间?
只是想知道共享内存的关键是文件名还是 inode。
我有一个名为 .last 的文件,它只是一个指向名为 YYYYMMDDHHMMSS 的文件的硬链接。
一个目录看起来像这样:
20110101143000
.last
Run Code Online (Sandbox Code Playgroud)
.last 只是到 20110101143000 的硬链接。
一段时间后,创建了一个新文件
20110101143000
20110622083000
.last
Run Code Online (Sandbox Code Playgroud)
然后我们删除 .last,并重新创建它以引用新文件。
我们的软件在这些更新期间持续运行,使用 MAP_SHARED 映射 .last 文件。处理完文件后,软件可能会将其缓存几分钟,而不是取消映射。在一台物理服务器上,有 12-24 个软件实例同时运行。不同的实例通常会同时映射同一个文件。我的问题是:
linux 是使用文件名来锁定共享内存,还是使用 inode?
鉴于这种情况:
如果 linux 使用 inode,那么 proc A 和 B 将看到映射到不同文件的不同内存块,这就是我们想要的。如果 linux 使用文件名,那么 A 和 B 都会看到映射到新文件的相同内存块。B 没问题,但是当分片块中的内存发生变化时,A 崩溃了。
有谁知道它实际上是如何工作的?我要测试,但如果结果是基于名称的,除非有人知道诀窍,否则我就完蛋了。
谢谢!
我们经常使用strace.我们想将一些文本输出到strace中以标记代码已达到的位置.到目前为止,我看到人们已经完成它的方式是统计一个不存在的文件.文件名只是他们想要在strace中看到的文本.它非常快,但我确信有更好的方法.我担心即使挂载点是伪造的,也可能会有大量代码和内核锁被命中.有任何想法吗?
我有一个课程模板CFoo<T>.我想允许隐式转换为其他实例化CFoo,但仅限于那些模板参数是基类的人T.
我尝试使用SFINAE,但我的尝试都没有用于我尝试的任何编译器(VC 2012或gcc):
#include <type_traits>
template <class T> class CFoo {
public:
template <class Q> operator
// typename std::enable_if<std::is_base_of<Q, T>::value, CFoo<Q>&>::type // SHOULD WORK?
// typename std::enable_if<1, CFoo<Q>&>::type // SHOULD WORK?
CFoo<Q>& // compiles, but doesn't restrict on Q like I want
() const {
return *(CFoo<Q>*)this;
}
};
class A {};
class B : public A {};
int main(int argc, char* argv[])
{
CFoo<B> b;
CFoo<A>& a = b;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么SFINAE的任何评论尝试都没有在这里工作?在这两种情况下,我只是因为无效的初始化而得到错误 …
C#是否在此处框出结构?
struct S { int x; }
void foo(ref S s) { s.x = 1; }
main {
var s = new S();
foo(ref s); <-- boxing??
}
Run Code Online (Sandbox Code Playgroud)
我听说过关于类中的结构的怪异内容。这里有拳击吗?这是通过成员的副本吗?
class C { S s; }
main {
var c = new C();
foo(ref c.s); <-- boxing here?? copy here???
}
void foo(ref S s) { s.x = 1; }
Run Code Online (Sandbox Code Playgroud)