到现在还是对 Interlocked* 系列函数不是很了解

Sandrer 2017-11-14 04:53:55
MSDN 上说的是保证同一时间只有一条线程可对其访问
我不明白的就是"访问"这个词, 究竟是在写时其它人不能读, 还是说在写时其它人不能读和写???
MSDN 上还说是将变量所在内存保护不允许其它人进入, 那是不是可以理解为在写时不能被其它人读和写?

那如果某个时刻我根据该变量做判断, 根据判断结果做其它事情, 那么在判断完后刚好有线程将变量改变了, 那怎么办?

volatile long m_l = 0;

if (m_l == 100)
{
// 程序执行到这里, 判断已经完成
// 如果这时其它地方调用 Interlocked* 系列函数改变 m_l 的值
// 那我这个判断是不是多余的?
// ....
}


Interlocked* 系列函数可以用在什么场合?
是不是只能用在不能用于判断的场合?
...全文
298 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-11-16
  • 打赏
  • 举报
回复
《Windows核心编程》
oyljerry 2017-11-16
  • 打赏
  • 举报
回复
引用 10 楼 Sandrer 的回复:
[quote=引用 6 楼 oyljerry 的回复:] 当然需要所有的线程都用interlocked去操作这个变量,才会各个线程之间会有锁定的动作,这样就能保证多个线程都修改这个变量的时候是原子操作,比如两个都是+1,那么最终结果肯定是+2,而不是最终可能出现+1 如果一个线程没有用interlocked去读取变量,那么他就可能读取到修改前的变量,或者修改后的变量,都有可能,未知
更正一下8楼的话 所以我问题的重点还是在于, 一个线程访问变量的同时, 是不是其它线程的访问或者调用interlocked*函数都会被挂起 这个"访问"其实是只读的意思~[/quote] 你没用interlocked的函数,直接读取变量,不会影响其他函数的调用挂起什么的,而是直接读
danscort2000 2017-11-16
  • 打赏
  • 举报
回复
你要这么理解 如果你所有的代码针对你的操作数,例如 i 无论读写或者xor add del 都采用interlocked系列函数去操作 那么系统保证,无论你开启了多少个线程去同时执行读写xor add del等操作, 针对i 的读写始终有且只有一个操作发生,而不会同时发生,也就是其实多个线程是需要排队操作的 而如果你在使用interlocked系列函数的时候,你代码中还用了直接读写的操作,例如 if(i==0) { } 例如这样的判断条件,那么这个i是无法保证当时数字是多少 如果你同时还使用了例如 if(i==0) i++ 之类的操作函数,那使用interlocked系列函数就完全失去了意义 也就是,如果你对i使用了interlocked操作,你必须保证所有线程所有代码针对i的读写测试都使用interlocked,任何一处打破这个约定,使用这个函数的意义就没有了 另外interlocked系列是个原子操作,什么是原子操作,就是系统保证针对i的读写测试等interlocked系列函数的执行不会被软中断,因此理论上interlocked系列函数的效率要远远高于使用锁保护的操作,如果你不是为了超高效率,没必要使用interlocked
brk1985 2017-11-16
  • 打赏
  • 举报
回复
补充15楼:InterlockedExchangeAdd返回值是增加前的旧值,用InterlockedExchangeAdd((LPLONG)&g_Value,0)可以表示当前值
brk1985 2017-11-16
  • 打赏
  • 举报
回复
InterlockedExchangeAdd((LPLONG)&g_Value,0) 这么读应该可以读到当前变量值吧!
danscort2000 2017-11-15
  • 打赏
  • 举报
回复
引用 4 楼 Sandrer 的回复:
[quote=引用 2 楼 danscort2000 的回复:] Interlocked* 系列函数是一个原子操作, 也就是系统保证你在执行的时候不会者被其他线程切入等操作 例如 当你执行 i=i+1的时候[i初始化为0],代码执行过程中的i,是可以在执行期间被其他线程抢先切入修改的[例如被其他线程修改为1],可能出现值出现混乱引发程序崩溃 但是如果你用Interlocked*系列函数,所有针对i的操作都使用Interlocked*,那么即使同时有100个线程在执行不同的针对i的加或者减,系统都会保证是一个顺序的原子操作 不会出现几个线程同时修改i值的情况发生
interlocked* 函数并没有提供只读功能的函数, 所有函数都只是写 我主要想知道的是: 1. 在线程A我读这个变量的同时(if (i == 100) 或 n = i), 线程B通过 interlocked* 来操作这个变量时是不是会被挂起, 直到线程A读完这个变量后线程B中的interlocked*函数才会继续执行下去 2. 还是说不同线程在使用 interlocked* 系列函数的时候才是锁定状态, 其它不使用该系列函数的只读方式都是不锁定的[/quote] interlocked系列函数里有测试数值的函数,返回值就是你调用完成后的瞬间值,但是 interlocked大部分函数只有在已经淘汰的Intel Itanium 处理器平台有效,X86/X64平台能适用的很少
oyljerry 2017-11-15
  • 打赏
  • 举报
回复
当然需要所有的线程都用interlocked去操作这个变量,才会各个线程之间会有锁定的动作,这样就能保证多个线程都修改这个变量的时候是原子操作,比如两个都是+1,那么最终结果肯定是+2,而不是最终可能出现+1 如果一个线程没有用interlocked去读取变量,那么他就可能读取到修改前的变量,或者修改后的变量,都有可能,未知
Sandrer 2017-11-15
  • 打赏
  • 举报
回复
引用 3 楼 smwhotjay 的回复:
Interlocked 方便同步单个变量。 具体看 win核心编程
我也知道是这样, 包括书上网上都是这样说. 但我还是没有了解到它怎么用, 网上书上说的都只是怎么去同步改这个值 而我题目主要问的是读这个值会不会与写这个值同步, 还有具体的应用场合(包括这个值可以用来做什么) 提个小意见, 就不要和某老师一样啦, 碰到别人的提问都让别人去找书, 最起码也说下在书的哪里有介绍吧 再说了, 如果每个人都能通过看书解决所有问题的话, 那 CSDN 技术论坛就没有存在的必要了不是吗? 我相信能来这里提问的, 都有自己的想法, 或者是没有在对的地方找到正确的内容? 或者是在对的地方找到了不明白的内容? 或者是...... 我自己本身出来工作10多年, 接触编程也有8,9年了, 看过的技术类书籍也不下20本, 像你说的或者某些老师说的书, 难道这么"有名"的书就没看过吗? 不可否认书能帮到人, 但书不是活的, 人才是活的, 来这里提问不是为了让活人去找死物去闭门造车, 而是经验技术的交流
Sandrer 2017-11-15
  • 打赏
  • 举报
回复
引用 2 楼 danscort2000 的回复:
Interlocked* 系列函数是一个原子操作, 也就是系统保证你在执行的时候不会者被其他线程切入等操作 例如 当你执行 i=i+1的时候[i初始化为0],代码执行过程中的i,是可以在执行期间被其他线程抢先切入修改的[例如被其他线程修改为1],可能出现值出现混乱引发程序崩溃 但是如果你用Interlocked*系列函数,所有针对i的操作都使用Interlocked*,那么即使同时有100个线程在执行不同的针对i的加或者减,系统都会保证是一个顺序的原子操作 不会出现几个线程同时修改i值的情况发生
interlocked* 函数并没有提供只读功能的函数, 所有函数都只是写 我主要想知道的是: 1. 在线程A我读这个变量的同时(if (i == 100) 或 n = i), 线程B通过 interlocked* 来操作这个变量时是不是会被挂起, 直到线程A读完这个变量后线程B中的interlocked*函数才会继续执行下去 2. 还是说不同线程在使用 interlocked* 系列函数的时候才是锁定状态, 其它不使用该系列函数的只读方式都是不锁定的
smwhotjay 2017-11-15
  • 打赏
  • 举报
回复
Interlocked 方便同步单个变量。 具体看 win核心编程
danscort2000 2017-11-15
  • 打赏
  • 举报
回复
Interlocked* 系列函数是一个原子操作, 也就是系统保证你在执行的时候不会者被其他线程切入等操作 例如 当你执行 i=i+1的时候[i初始化为0],代码执行过程中的i,是可以在执行期间被其他线程抢先切入修改的[例如被其他线程修改为1],可能出现值出现混乱引发程序崩溃 但是如果你用Interlocked*系列函数,所有针对i的操作都使用Interlocked*,那么即使同时有100个线程在执行不同的针对i的加或者减,系统都会保证是一个顺序的原子操作 不会出现几个线程同时修改i值的情况发生
schlafenhamster 2017-11-15
  • 打赏
  • 举报
回复
Interlocked 操作都是 读写 一起的, 如 InterlockedIncrement 要先 从内存 读到 寄存器 ,寄存器 +1 ,存入内存。
Sandrer 2017-11-15
  • 打赏
  • 举报
回复
引用 6 楼 oyljerry 的回复:
当然需要所有的线程都用interlocked去操作这个变量,才会各个线程之间会有锁定的动作,这样就能保证多个线程都修改这个变量的时候是原子操作,比如两个都是+1,那么最终结果肯定是+2,而不是最终可能出现+1 如果一个线程没有用interlocked去读取变量,那么他就可能读取到修改前的变量,或者修改后的变量,都有可能,未知
更正一下8楼的话 所以我问题的重点还是在于, 一个线程访问变量的同时, 是不是其它线程的访问或者调用interlocked*函数都会被挂起 这个"访问"其实是只读的意思~
Sandrer 2017-11-15
  • 打赏
  • 举报
回复
引用 7 楼 danscort2000 的回复:
interlocked系列函数里有测试数值的函数,返回值就是你调用完成后的瞬间值,但是 interlocked大部分函数只有在已经淘汰的Intel Itanium 处理器平台有效,X86/X64平台能适用的很少
那是不是说, interlocked* 系列函数只能保证同步写的准确性, 但不保证读时候的准确性?
Sandrer 2017-11-15
  • 打赏
  • 举报
回复
引用 6 楼 oyljerry 的回复:
当然需要所有的线程都用interlocked去操作这个变量,才会各个线程之间会有锁定的动作,这样就能保证多个线程都修改这个变量的时候是原子操作,比如两个都是+1,那么最终结果肯定是+2,而不是最终可能出现+1 如果一个线程没有用interlocked去读取变量,那么他就可能读取到修改前的变量,或者修改后的变量,都有可能,未知
貌似 interlocked* 系列函数就没有去读的, 都是写的 最多就调用完成后返回修改前的值, 只加或只减的就返回改完后的值 所以我问题的重点还是在于, 一个线程访问变量的同时, 是不是其它线程的访问或者调用interlocked*函数都会被挂起
Eleven 2017-11-14
  • 打赏
  • 举报
回复
可以理解为多个线程同时读写一个变量~

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧