老师,你好,关于共享内存加锁及竞争条件有个疑问~
假设有这样的场景,所有的工作进程都可以执行到如下操作序列,dict.get, dict.set。进程1执行了dict.get之后,进程2这时获得了共享内存锁,这个时候执行了dict.set,然后进程1再次获得了共享内存锁,执行dict.set之前,看到的其实已经是共享内存中比较老的数据了,然后执行了dict.set操作,覆盖了进程2的操作。这里等待获得共享内存锁的操作,应该是个阻塞操作,按照文中的说法,阻塞操作应该不会产生竞争。可是这里应该是产生了竞争了是吧?难道说这里涉及到把主动权交给nginx的事件循环了吗?
作者回复: 我的理解哈,多个 worker 共享了同一个 shared dict,你这里的描述更像是数据库里面的事务,要达到这个效果有两个方法:
1. 如果用 incr 能够满足你的需求的话,就不要用 set;
2. 否则就需要你自己去手工加锁。
如果是 lrucache 的 get 和 set 操作就不会有这个问题,因为它只存在于一个 worker 内。