在共享数据中使用原子整数
Usage of atomic integer in a shared data
我正在研究 OS 和同步,我想到了在不同步的情况下处理这个共享数据,但我不确定它是否会 work.Here 是代码
现在,竞争条件显然是共享中的递增和递减 data.But 如果整数变量是原子的怎么办?我想当我只是 CS 的初学者时我读过一些关于这个的东西所以问题可能不是是 perfect.As 据我记得它阻止了一些东西以防止同时递增和递减 time.Now,我对此有点困惑,因为如果原子变量真的有效,就不需要找到像这样的简单代码的同步方法。
注意:代码已被删除,因为它只是改变了人们的焦点并且答案提供了足够的信息
就目前而言,并发调用代码确实不安全,因此必须有某种同步来防止这种情况发生。
现在,关于使 num_processes
成为原子的想法,这可行。不过,这不是一个简单的替换,特别是与最大值相比,递增必须以原子方式完成,而不是分两步完成,否则你仍然有竞争条件。特别是,必须防止以下步骤:
- 线程 A 检查是否达到限制,但实际上没有。
- 线程 B 检查是否达到限制,但实际上没有。
- 线程 B 递增 PID 计数器。
- 线程 A 递增 PID 计数器。
每个步骤本身都是原子的,但显然这无助于防止 PID 溢出。相反,代码必须检查计数器是否未达到限制,然后以原子方式递增它。这也是一个常见的任务(比较和递增),所以你应该很容易找到现有的代码示例。
但是,我很确定这并不是所有涉及的代码,一些其他代码(例如 get_processID()
中或释放 PID 的代码)可能仍然需要对整个代码进行锁定。
对于您的代码,根本不需要同步,因为此处 num_processes
仅由一个进程递增和递减,即父级 process.And 并且 num_processes
不是此处的共享变量。要创建共享变量,您必须首先了解 UNIX 中的 shmget()
和 shmat()
函数。
如果两个或多个进程想要访问一个共享的 memory.An 操作,则竞争条件会出现,如果该操作将完全执行(即不切换)或根本不执行,则该操作将是原子的。例如
考虑共享数据的增量运算符。这个运算符不是原子的。因为如果转到增量运算符的较低级别指令,则此操作将分几步执行:
1. First load the value of variable in some register.
2. Add one with that loaded value and now result will be in some temporary register.
3. Store this result in the memory location / register that is pointed by that variable on which increment is performed.
现在如您所见,此操作分三步完成。因此,如果在完成这三个步骤之前切换到另一个进程,则会导致不良结果。有关更多信息,您可以从 link http://tutorials.jenkov.com/java-concurrency/race-conditions-and-critical-sections.html 中了解竞争条件。从上面可以看出 add, store, load
指令是原子的,因为考虑到没有电源故障或任何系统故障,它将完全执行或根本不执行。因此,要执行 increment operation
原子操作,我们需要使用 semaphores
或 monitors
进行一些同步。这些都是软件同步技术。我想现在你应该清楚这个话题了..
我正在研究 OS 和同步,我想到了在不同步的情况下处理这个共享数据,但我不确定它是否会 work.Here 是代码
现在,竞争条件显然是共享中的递增和递减 data.But 如果整数变量是原子的怎么办?我想当我只是 CS 的初学者时我读过一些关于这个的东西所以问题可能不是是 perfect.As 据我记得它阻止了一些东西以防止同时递增和递减 time.Now,我对此有点困惑,因为如果原子变量真的有效,就不需要找到像这样的简单代码的同步方法。
注意:代码已被删除,因为它只是改变了人们的焦点并且答案提供了足够的信息
就目前而言,并发调用代码确实不安全,因此必须有某种同步来防止这种情况发生。
现在,关于使 num_processes
成为原子的想法,这可行。不过,这不是一个简单的替换,特别是与最大值相比,递增必须以原子方式完成,而不是分两步完成,否则你仍然有竞争条件。特别是,必须防止以下步骤:
- 线程 A 检查是否达到限制,但实际上没有。
- 线程 B 检查是否达到限制,但实际上没有。
- 线程 B 递增 PID 计数器。
- 线程 A 递增 PID 计数器。
每个步骤本身都是原子的,但显然这无助于防止 PID 溢出。相反,代码必须检查计数器是否未达到限制,然后以原子方式递增它。这也是一个常见的任务(比较和递增),所以你应该很容易找到现有的代码示例。
但是,我很确定这并不是所有涉及的代码,一些其他代码(例如 get_processID()
中或释放 PID 的代码)可能仍然需要对整个代码进行锁定。
对于您的代码,根本不需要同步,因为此处 num_processes
仅由一个进程递增和递减,即父级 process.And 并且 num_processes
不是此处的共享变量。要创建共享变量,您必须首先了解 UNIX 中的 shmget()
和 shmat()
函数。
如果两个或多个进程想要访问一个共享的 memory.An 操作,则竞争条件会出现,如果该操作将完全执行(即不切换)或根本不执行,则该操作将是原子的。例如
考虑共享数据的增量运算符。这个运算符不是原子的。因为如果转到增量运算符的较低级别指令,则此操作将分几步执行:
1. First load the value of variable in some register.
2. Add one with that loaded value and now result will be in some temporary register.
3. Store this result in the memory location / register that is pointed by that variable on which increment is performed.
现在如您所见,此操作分三步完成。因此,如果在完成这三个步骤之前切换到另一个进程,则会导致不良结果。有关更多信息,您可以从 link http://tutorials.jenkov.com/java-concurrency/race-conditions-and-critical-sections.html 中了解竞争条件。从上面可以看出 add, store, load
指令是原子的,因为考虑到没有电源故障或任何系统故障,它将完全执行或根本不执行。因此,要执行 increment operation
原子操作,我们需要使用 semaphores
或 monitors
进行一些同步。这些都是软件同步技术。我想现在你应该清楚这个话题了..