我在我的应用程序中有这段代码。 我怀疑它不是线程安全的,所以决定去问这个SOers。
int * volatile int_ptr; int count;
主题1:
void grow(int new_count) { if(new_count <= count) return; int * new_ptr = new int[new_count]; memset(new_ptr,new_count * sizeof(int)); memcpy(new_ptr,int_ptr,count); int * dum_ptr = (int *)InterlockedExchange((volatile long *)&int_ptr,(long)new_ptr) count = new_count; delete [] dum_ptr; }
主题2:
int get_value(int index) { return int_ptr[index]; }
我知道可以使用CRITICAL_SECTION,但是线程1可能在一周内工作一次,而线程2将在一天中工作数百万次。 在尝试访问int_ptr的99.99999%中,第二个线程将进入和退出关键部分为int_ptr 。 这对我来说没有意义。 该应用程序将只能在Windows 2000和更高版本的英特尔处理器显然多核。
multithreading进程的fork:所有进程内存被复制?
Linux的线程本地存储实现
“nice”会影响Java线程的优先级吗?
一起使用gevent和multiprocessing与subprocess通信
奇怪的线程NullReferenceException当读取存在的值?
这个代码是线程安全的吗? 如果不是,我该怎么做才能使线程安全? 我怎样才能读取int_ptr自动? 即:
int * dummy_ptr = read_atomic<int *>(int_ptr); return dummy_ptr[index];
一个解决scheme,包括std::vector ,使我更快乐,更舒适。
如果多个pthread使用相同的函数会发生什么情况
在Linux / Python2.7的终止()后,多处理器。池中产生新的childern?
Bash进程replace背景与作业控制
打电话给shmat两次
不,这不安全。 get_value可以读取int_ptr的值,然后调出。 然后另一个线程可以换出int_ptr并delete旧的值。 当get_value被换回时,它会尝试取消从int_ptr (已经被删除)读取的值。
更好的方法是基于“Read-copy-Update”(RCU) ,它已经在Linux中用得很好。 基本的原则是,你不要马上删除旧的值 – 你要等到某个时候才能保守地确定没有旧的指针值,然后删除它。
不幸的是,Windows上还没有RCU库的实现。 我想你可以尝试把urcu移植到Windows上。
不,这不对。 一种情况是thread2在get_value函数内部并且正在执行int_ptr[index] 。 既然它不是原子的,这可能需要几个指令。 通过这些指令的一半,线程上下文切换发生,并且thread1开始与grow一起执行。 这将delete[] int_ptr 。 现在,当thread2启动时,将遇到访问冲突。 你可以使用CCriticalSection来解决这个问题。 由于它不是内核对象,所以在Windows操作系统上的性能并不是很差。
考虑让线程1要求线程2执行更新或等待更新正在执行。
为了有用,线程2必须侦听来自系统其他部分的某种信号或消息。 消息传递机制或条件变量可以用新消息扩展。 还要考虑APC(有点像Unix信号)。
这需要实际要求而不是强行中止。 强制挂起一个线程并不能解决问题,因为线程可能会在任何时候挂起,包括在读取int_ptr和读取int_ptr[index] 。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。