Java规范保证原始变量赋值总是原子的(期望long和双精度)types.
相反,对应于着名的增量操作的获取和添加操作i++将是非原子的,因为导致读 - 修改 - 写操作.
假设这段代码:
public void assign(int b) {
int a = b;
}
Run Code Online (Sandbox Code Playgroud)
生成的字节码是:
public void assign(int);
Code:
0: iload_1
1: istore_2
2: return
Run Code Online (Sandbox Code Playgroud)
因此,我们看到赋值由两个步骤组成(加载和存储).
假设这段代码:
public void assign(int b) {
int i = b++;
}
Run Code Online (Sandbox Code Playgroud)
字节码:
public void assign(int);
Code:
0: iload_1
1: iinc 1, 1 //extra step here regarding the previous sample
4: istore_2
5: return
Run Code Online (Sandbox Code Playgroud)
知道X86处理器可以(至少是现代处理器)以原子方式操作增量操作,如上所述:
在计算机科学中,fetch-and-add CPU指令是一种特殊指令,它以原子方式修改存储器位置的内容.它用于在多处理器系统中实现互斥和并发算法,信号量的泛化.
因此,第一个问题:尽管字节码需要两个步骤(加载和存储),但是Java依赖于这样的事实:赋值操作是一个操作,无论处理器的体系结构如何都始终以原子方式执行,因此可以确保永久原子性(对于原始赋值) )在其规格?
第二个问题:用非常现代的X86处理器确认并且不跨不同架构共享编译代码是不对的,根本不需要同步 …
使用Django 1.8,如何在单个db事务中创建多个对象并写入db?
似乎以前的版本有@commit_manually.但是当我尝试修改此代码时:https://stackoverflow.com/a/29834940我得到一个例外
django.db.transaction.TransactionManagementError: The outermost 'atomic' block cannot use savepoint = False when autocommit is off.
Run Code Online (Sandbox Code Playgroud)
在我看过很多帖子中说要用"with transaction.atomic()"块包装,但这会在每个循环中击中db.
这是我的代码的简化版本.我没有运行它,但它应该显示我正在尝试做什么.
class Foo(models.Model):
Name = models.CharField( max_length=200 )
class Bar(models.Model):
Foos = models.ManyToManyField( foo )
class Processor(object):
def run(self,):
myBar = Bar.object.create()
myList = ['a', 'b', 'c', 'd']
if True:
set_autocommit( False )
for char in myList:
myFoo = Foo.objects.create(Name=char)
myBar.Foos.add( myFoo )
commit()
set_autocommit( True )
Run Code Online (Sandbox Code Playgroud)
我正在尝试进行所有这些更改,只打了一次db.我知道有model.objects.bulk_create,但我找不到处理m2m关系的方法.另外bulk_create不会返回db实例,因此我必须将它们从m2中拉出来以获取m2m关系.
我需要将并发系统放在一起,并Control.Concurrent.Chan在线程之间共享一个.将只有一个消费者和许多生产者.看看Chan文档,我没有看到任何关于可能在同一个频道上工作的消费者和制作者数量的警告,并且源代码似乎使用MVars 的默认"安全"访问器,因此我认为它应该是安全的.假设不应该有限制,但我不确定.所以,我的问题是......你知道haskell频道对于多个读者和制作人来说是否安全(一般情况下),对吗?
以下代码是一个原子指针类的框架,它取自PARSEC基准套件中用于共享内存多处理器的模拟退火应用程序.
在该应用中,中央数据结构是图(更具体地,集成电路的网表).图中的每个节点都有一个指示其物理位置的属性.该算法产生许多线程并且每个线程重复并随机选择两个节点并交换它们的物理位置,如果这导致芯片的更好的路由成本.
因为图形很大并且每个线程都可以选择任何一对节点,所以唯一可行的解决方案是无锁并发数据结构(CDS).这就是为什么以下AtomicPtr类是至关重要的(它用于以无锁方式原子地交换指向两个物理位置对象的指针).该函数atomic_load_acq_ptr()是在汇编代码中定义的并且与之紧密对应std::atomic<T*>::load(memory_order_acquire).
我想用C++ 11原子实现该CDS.
template <typename T>
class AtomicPtr {
private:
typedef long unsigned int ATOMIC_TYPE;
T *p __attribute__ ((aligned (8)));
static const T *ATOMIC_NULL;
inline T *Get() const {
T *val;
do {
val = (T *)atomic_load_acq_ptr((ATOMIC_TYPE *)&p);
} while(val == ATOMIC_NULL);
return val;
}
inline void Swap(AtomicPtr<T> &X) {
// Define partial order in which to acquire elements to prevent deadlocks
AtomicPtr<T> *first;
AtomicPtr<T> *last;
// Always process elements …Run Code Online (Sandbox Code Playgroud) 大多数语言都提供原子int操作的功能(添加,比较和交换等).
为什么不浮动类型?
我正在尝试使用C#生成一个巨大的文本文件,另一个进程不断查看该位置并尝试拾取该文件(如果可用).
为了使下面的文件原子是以下步骤:
1 - Write to file : Filename_temp.txt
2 - Check if Filename.txt already exists then Delete
3 - Do a File.Move to the same destination
From filename : Filename_temp.txt
TO : Filename.txt
Run Code Online (Sandbox Code Playgroud)
由于C#没有重命名,我必须依赖File.Move,这是否确保移动操作是原子的还是有另一种方法来实现这种原子性?
我知道如果没有锁定,增量操作在C++中不是原子操作.
JVM是否会对其iinc指令实现添加任何锁定?
我正在努力学习并更好地理解多线程,但我对原子函数(如fetch-and-add)的行为感到困惑.在fetch-and-add的特定情况下,我理解一个值(假设当前等于5的x)被一个增量值(假设为3)加到,结果sum(8)被写入x的放在内存中,但返回旧的值(5).
在不同的地方还有其他几个这样的函数(比如OpenGL的原子函数,Java的AtomicIntegers,还有更多的区域)就像这样.但我不明白的是为什么代码中的一个地方想要写入内存但仍然首先返回它想要修改的值.任何人都可以帮助阐明这一点吗?
代码库有一个COMPILER_BARRIER定义为的宏__asm__ volatile("" ::: "memory").宏的目的是防止编译器跨屏障重新排序读取和写入.请注意,这显然是编译器障碍,而不是处理器级别的内存障碍.
因此,这是相当便携的,因为AssemblerTemplate中没有实际的汇编指令,只有volatile和memoryclobber.因此,只要编译器遵循GCC扩展Asm语法,它就可以正常工作.尽管如此,我很好奇如果可能的话,在C++ 11 atomics API中表达它的正确方法是什么.
以下似乎可能是正确的想法:atomic_signal_fence(memory_order_acq_rel);.
我的理由是:
<atomic>API中,仅需要atomic_signal_fence并且atomic_thread_fence不需要用于操作的存储器地址.atomic_thread_fence 影响内存排序,我们不需要编译器障碍.memoryExtended Asm版本中的clobber不区分读取和写入,因此看起来我们需要获取和释放语义,因此memory_order_acq_rel似乎至少需要.memory_order_seq_cst 似乎没必要,因为我们不需要跨线程的总顺序 - 我们只对当前线程中的指令排序感兴趣.是否有可能__asm__ volatile("" ::: "memory")用C++ 11 atomics API 表达完全可移植的等价物?如果是这样,是否atomic_signal_fence使用正确的API?如果是这样,这里适当/需要什么内存顺序参数?
或者,我在这里的杂草中,有一个更好的方法来解决这个问题吗?
我有一个具有递增和递减方法的计数器类,两个方法都是同步的.
public class Counter {
int count = 0;
public synchronized void increment(){
count++;
}
public synchronized void decrement(){
count--;
}
}
Run Code Online (Sandbox Code Playgroud)
从这个例子可以看出,竞争条件不会发生,只有一个线程可以访问增量或减量方法.
现在代替整数原语,如果我用Atomic Integer修改了计数器类并删除了synchronized关键字,我们可以实现同样的目的吗?
public class Counter {
AtomicInteger count = new AtomicInteger();
public void increment(){
count.incrementAndGet();
}
public void decrement(){
count.decrementAndGet();
}
}
Run Code Online (Sandbox Code Playgroud)