如果已经回答了这个问题,或者我错过了一些明显的东西,请道歉。
我试图了解std::atomic
对原子性的保证有多深。例如,如果我们有
std::atomic<int> a(0);
a.store(1);
商店运营是原子的。但是,如果我们有嵌套的原子操作会发生什么,例如:
std::atomic<int> a(0);
std::atomic<int> b(1);
a.store(++b);
我的理解是++b
是原子的,store()
也是。{1}}。我是否正确地认为这可以保证2
原子地存储在a
中?
更重要的是,如果a
和b
在线程T1
和T2
之间共享,是否保证两个线程执行的a.store(++b);
将会在每个线程中以原子方式将b
的递增值(由各个线程看到)存储到a
中?换句话说,可以将T2
&#34;对接在&#34;并且在 b
已经增加一次之后再次增加{em} {em> 之前将结果存储到T1
中{{1} }}?
答案 0 :(得分:2)
增量是原子的,存储是原子的,但两个操作不是。第一个线程有可能递增b
,被挂起,然后另一个线程递增b
并将该值存储在a
中,然后第一个线程恢复并存储它(现在是陈旧的) b
的值a
。
答案 1 :(得分:1)
原子性不构成。
假设没有其他人写过@Embeddable
public class SnippetDetailPrimaryEntity implements Serializable {
@ManyToOne
@JoinColumn(name = "snpt_id")
private SnippetEntity snippetEntity;
@Column(name = "lang_cd")
private String language;
}
@Entity
@Table(name = "snippet_detail")
public class SnippetDetailEntity implements Serializable {
@EmbeddedId
private SnippetDetailPrimaryEntity snippetDetailPrimaryEntity;
@Column(name = "snpt_type_cd")
private String snippetType;
@Column(name = "snpt_desc")
private String snippetDescription;
@Column(name = "snpt_txt")
private String snippetText;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "cretn_ts")
private Date creationTimeStamp;
@Column(name = "cretn_user_id")
private String creationUserId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updt_ts")
private Date updatedTimeStamp;
@Column(name = "updt_user_id")
private String updatedUserId;
}
和a
并且另一个线程尝试在它们存在后读取它们,并且它们读取b
然后b
,则可能的读取正是:
a
如果他们阅读{b,a}
{1,0}
{2,0}
{2,2}
然后a
:
b
在这种情况下与{a,b}
{0,1}
{0,2}
{2,2}
相同,然后是b
。
答案 2 :(得分:1)
> git clone https://github.com/vim/vim.git
> cd src
> mingw32-make -f Make_ming.mak gvim.exe
> gvim.exe -c "%s,Sun,SUNDAY,gicp#" testfile.txt
> git diff ex_cmds.c
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -5095,6 +5095,7 @@ do_sub(exarg_T *eap)
#endif
); ++lnum)
{
+ int show_change=FALSE;
nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum,
(colnr_T)0, NULL, NULL);
if (nmatch)
@@ -5432,8 +5433,10 @@ do_sub(exarg_T *eap)
}
if (typed == 'n')
break;
- if (typed == 'y')
+ if (typed == 'y') {
+ show_change=TRUE;
break;
+ }
if (typed == 'l')
{
/* last: replace and then stop */
@@ -5779,6 +5782,11 @@ skip:
line_breakcheck();
}
+ if (show_change) {
+ print_line(curwin->w_cursor.lnum, subflags.do_number, subflags.do_list);
+ do_sleep(10);
+ (void) plain_vgetc(); // wait for keypress
+ }
+
相当于
a.store(++b);