关于"UPDATE ... SET .. WHERE ..."声明的原子性,我有一个相当基本和普遍的问题.
有一张桌子(没有额外的约束),
+----------+
| id | name|
+----------+
| 1 | a |
+----+-----+
Run Code Online (Sandbox Code Playgroud)
现在,我将"同时"执行以下4个语句(同时).
UPDATE table SET name='b1' WHERE name='a'
UPDATE table SET name='b2' WHERE name='a'
UPDATE table SET name='b3' WHERE name='a'
UPDATE table SET name='b4' WHERE name='a'
Run Code Online (Sandbox Code Playgroud)
是否只有一个UPDATE语句将与表更新一起执行?或者,多个UPDATE语句是否可以真正更新表?
我是否需要额外的事务或锁定才能让一个UPDATE写入值到表中?
谢谢
[编辑] 4个UPDATE语句从不同进程并行执行.[编辑]与Postgresql
我必须在C#中进行一系列方法调用,这样,如果其中一个失败,则不应调用后续方法.简而言之,这组调用应该是原子的.我如何在C#中实现这一目标?
我正在阅读boost::shared_ptr源代码并发现它使用此函数来增加shared_ptr的使用计数(引用计数):
inline void atomic_increment( int * pw )
{
//atomic_exchange_and_add( pw, 1 );
__asm__
(
"lock\n\t"
"incl %0":
"=m"( *pw ): // output (%0)
"m"( *pw ): // input (%1)
"cc" // clobbers
);
}
Run Code Online (Sandbox Code Playgroud)
为什么不简单地使用operator++这样做呢?这会带来更好的表现吗?
我需要插入有两列的数据库 -
ID PrimaryKey String
ACCOUNT String
Run Code Online (Sandbox Code Playgroud)
这意味着每个线程应始终使用唯一ID,我也需要ID在Account列中存储相同的ID .因此,如果ID is 1那么在数据库中它应该存储为
ID Account
1 SomeString+1
2 SomeString+2
3 SomeString+3
....
..
100 SomeString+100
Run Code Online (Sandbox Code Playgroud)
我总是在Account列中将该userID与该String连接起来.
下面是我的多线程代码,它将产生多个线程 - 每个线程将在每次使用时获得一个新的唯一ID AtomicInteger.它会插入ID到ID column还追加一条ID到Account列
但不知何故,在我的下面的程序中,我在该数据库中看到的是 -
ID Account
1 String+2
2 String+1
3 String+3
Run Code Online (Sandbox Code Playgroud)
哪个不对.它应该像这样 -
ID Account
1 String+1
2 String+2
3 String+3
Run Code Online (Sandbox Code Playgroud)
下面是代码
public static void main(String[] args) {
final int noOfThreads = 4;
final int noOfTasks = …Run Code Online (Sandbox Code Playgroud) 我读到原始数据类型,如布尔,字节,短,字符,整数和浮点数都是原子的。像long和double这样的64位数据类型则不是。
但是,这是什么意思?当我有2个在int变量上递增和递减的线程时,有时我仍会遇到竞态条件。
例如将金额添加到变量的字节码。
getfield #2 <Field int amount>
iload_1
iadd
putfield #2 <Field int amount>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,原子操作是否是每个单个操作(getfield,iadd ...),而不是全部加法?
我正在开发基于ARM Cortex-M3架构(LPC1769)的共享数据库,并且想知道是否需要互斥或锁定写入。
32位浮点读写原子吗?
-编辑-我为uint32_t和float的写函数添加了反汇编:
00000000 <setSharedDataUint>:
0: b480 push {r7}
2: b083 sub sp, #12
4: af00 add r7, sp, #0
6: 4603 mov r3, r0
8: 6039 str r1, [r7, #0]
a: 71fb strb r3, [r7, #7]
c: 79fb ldrb r3, [r7, #7]
e: 4a05 ldr r2, [pc, #20] ; (24 <setSharedDataUint+0x24>)
10: 00db lsls r3, r3, #3
12: 4413 add r3, r2
14: 683a ldr r2, [r7, #0]
16: 605a str r2, [r3, #4]
18: 370c adds r7, …Run Code Online (Sandbox Code Playgroud) 这段代码来自 Pintos 源码:https : //www.cs.usfca.edu/~benson/cs326/pintos/pintos/src/threads/synch.c
void
sema_down (struct semaphore *sema)
{
enum intr_level old_level;
ASSERT (sema != NULL);
ASSERT (!intr_context ());
old_level = intr_disable ();
while (sema->value == 0)
{
list_push_back (&sema->waiters, &thread_current ()->elem);
thread_block ();
}
sema->value--;
intr_set_level (old_level);
}
Run Code Online (Sandbox Code Playgroud)
采取信号量的事实是sema->value--;。如果它有效,它必须是一个原子操作。我们怎么知道它实际上是原子操作?我知道现代 CPU 保证对齐的内存操作(对于字/双字/四字 - 它取决于)是原子的。但是,在这里,我不相信为什么它是原子的。
首先引自From JLS 8 Sec 17.7
无论是否将它们实现为32位或64位值,对引用的写入和读取始终是原子的.
这是让我感到困惑的场景,给定Employee类和此类中名为calculate的方法,该方法返回对Employee实例的引用.
Employee emp = calculate();
Run Code Online (Sandbox Code Playgroud)
当对变量的写入是原子时,这意味着在原子操作完成之前没有其他线程可以访问该变量,并且在给定的赋值示例中,写入的原子性包括对赋值右侧的评估(但是复数),或者写入的原子性是否仅适用于完全评估右侧的情况,然后实际完成写入操作.
换句话说,我问的是,在评估过程中calculate(),emp对其他线程的访问权限是否被拒绝,或者仅在分配的右侧被完全评估并且写入操作emp开始时才被拒绝?
对不起,很长一段时间,非常感谢!
假设我让atomic<int> i;线程 A 使用 memory_order_release 执行原子存储/交换。接下来,线程 B 使用 memory_order_release 执行原子存储。线程 C 执行原子 fetch_add(0, memory_order_acquire);
线程 C 是否从线程A 和 B或仅从线程 B获取依赖项?
当您查看一些Objective-C代码时,您经常会看到定义为非原子的类属性.为什么?当你不使用线程时,它是否会给你一些性能提升,还是有其他原因?
atomicity ×10
atomic ×3
java ×3
c++ ×2
arm ×1
boost ×1
c ×1
c# ×1
cocoa ×1
concurrency ×1
interrupt ×1
objective-c ×1
pintos ×1
properties ×1
shared-ptr ×1
sql ×1
stdatomic ×1
x86 ×1