当使用 pthread 时,我可以在线程创建时传递数据。
将新数据传递到已经运行的线程的正确方法是什么?
我正在考虑制作一个全局变量并让我的线程从中读取。
谢谢
最佳答案
那肯定行得通。基本上,线程只是共享相同内存空间的轻量级进程。位于该内存空间中的全局变量可供每个线程使用。
诀窍不在于读者,而在于作者。如果你有一个简单的全局内存块,比如 int
,那么分配给那个 int
可能是安全的。 Bt 考虑一些更复杂的东西,比如 struct
。为了明确起见,假设我们有
struct S { int a; float b; } s1, s2;
现在 s1,s2
是 struct S
类型的变量。我们可以初始化它们
s1 = { 42, 3.14f };
我们可以分配它们
s2 = s1;
但是当我们为它们赋值时,处理器不能保证一步完成对整个结构的赋值——我们说它不是原子。现在让我们想象两个线程:
thread 1:
while (true){
printf("{%d,%f}\n", s2.a, s2.b );
sleep(1);
}
thread 2:
while(true){
sleep(1);
s2 = s1;
s1.a += 1;
s1.b += 3.14f ;
}
我们可以看到我们希望 s2
具有值 {42, 3.14}, {43, 6.28}, {44, 9.42}
... .
但是我们看到打印出来的可能是什么
{42,3.14}
{43,3.14}
{43,6.28}
或
{43,3.14}
{44,6.28}
等等。问题是线程 1 可能会在该分配期间随时获得控制权并“查看”s2。
寓意是虽然全局内存是一种完全可行的方法,但您需要考虑线程相互交叉的可能性。对此有多种解决方案,最基本的解决方案是使用信号量。信号量有两个操作,从荷兰语中混淆地命名为 P 和 V。
P 简单地等到变量为 0 并继续,将 1 加到变量; V 从变量中减去 1。唯一特别的是它们自动执行此操作——它们不会被打断。
现在,你编码为
thread 1:
while (true){
P();
printf("{%d,%f}\n", s2.a, s2.b );
V();
sleep(1);
}
thread 2:
while(true){
sleep(1);
P();
s2 = s1;
V();
s1.a += 1;
s1.b += 3.14f ;
}
并且您可以保证在线程 1 尝试打印时您永远不会让线程 2 完成一半的分配。
(顺便说一下,Pthreads 有信号量。)
关于c++ - 如何将数据传递给正在运行的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6171350/