C# 在两个线程之间传递数据时,如何确保线程看到最新的值?
我通过PInvoke调用使用本机库,该调用返回字节*,并希望确保在生产者/消费者场景中,消费者线程获取最新数据 我这里有一个非常做作的例子,试图说明我的问题。我知道C# 在两个线程之间传递数据时,如何确保线程看到最新的值?,c#,multithreading,pinvoke,C#,Multithreading,Pinvoke,我通过PInvoke调用使用本机库,该调用返回字节*,并希望确保在生产者/消费者场景中,消费者线程获取最新数据 我这里有一个非常做作的例子,试图说明我的问题。我知道消费者中存在“热循环”(这只是一个例子,实际代码要大得多,粘贴在这里是不可行的) 公共不安全类线程示例{ PInvokeResult类{ 公共字节*数据; 公共Int32长度; } //用于同步的共享对象 对象SyncRoot=新对象(); 队列工作队列=新队列(); //生产者线程 无效生产者(){ while(true){ PIn
消费者
中存在“热循环”(这只是一个例子,实际代码要大得多,粘贴在这里是不可行的)
公共不安全类线程示例{
PInvokeResult类{
公共字节*数据;
公共Int32长度;
}
//用于同步的共享对象
对象SyncRoot=新对象();
队列工作队列=新队列();
//生产者线程
无效生产者(){
while(true){
PInvokeResult工作项目;
workItem=新的PInvokeResult();
workItem.Data=PInvokeNativeLongRunningCall(out workItem.Length);
锁定(同步根){
WorkQueue.Enqueue(workItem);
}
}
}
//消耗线程
无效消费者(){
while(true){
bool workAvailable=false;
PInvokeResult workItem=null;
锁定(同步根){
如果(WorkQueue.Count>0){
workItem=WorkQueue.Dequeue();
workAvailable=true;
}
}
如果(可用){
进程工作项(工作项);
PInvokeReturnPointerBuffer(工作项数据);
}
}
}
}
这里的锁是否足以确保从PInvokeResult上的字节*
指针读取的数据不会指向消费者的“过时”数据
我这里所说的陈旧数据是指以下情况:
PInvokeNativeLongRunningCall
调用返回一个特定字节*缓冲区PInvokeReturnPointerBuffer将其返回到本机代码
1开始。
这是一种语言必须考虑的问题,还是完全由CPU自己处理 是的,锁够了。你可以免费获得它使用的内存屏障。即使我害怕的数据“过时”是来自正在运行的应用程序的本机部分?我认为这并不重要,CPU不关心正在执行的语言类型,等等。对,处理器只知道一种数据。
public unsafe class ThreadExample {
class PInvokeResult {
public Byte* Data;
public Int32 Length;
}
// Shared Objects Used For Synchronization
Object SyncRoot = new Object();
Queue<PInvokeResult> WorkQueue = new Queue<PInvokeResult>();
// Producer Thread
void Producer() {
while (true) {
PInvokeResult workItem;
workItem = new PInvokeResult();
workItem.Data = PInvokeNativeLongRunningCall(out workItem.Length);
lock (SyncRoot) {
WorkQueue.Enqueue(workItem);
}
}
}
// Consume Thread
void Consumer() {
while (true) {
bool workAvailable = false;
PInvokeResult workItem = null;
lock (SyncRoot) {
if (WorkQueue.Count > 0) {
workItem = WorkQueue.Dequeue();
workAvailable = true;
}
}
if (workAvailable) {
ProcessWorkItem(workItem);
PInvokeReturnPointerBuffer(workItem.Data);
}
}
}
}