假设我有以下C代码:
clock_tick
现在我在中断期间调用clock_ticks
(即:递增get_clock_ticks()
变量),同时从main()
函数调用clock_ticks
(即:在中断之外)。
我的理解是volatile
应该声明为main()
,否则编译器可以优化其访问权限并使get_clock_ticks(void)
认为值没有改变(当它实际上从中断改变时) )。
我想知道是否在那里使用main()
函数,而不是直接从static
访问变量(即:不将其声明为volatile
)实际上可以强制编译器加载变量即使它没有被宣布为易失性,也要从内存中获取。
我想知道这是因为有人告诉我这可能会发生。这是真的吗?在哪些条件下?如果我使用" getter"无论如何我都应该总是使用 //Map Declaration
private static Map<Integer, User> users = new HashMap<Integer, User>();
.....
@GET
@Path("/adduser")
public List<User> adduser(
@QueryParam("username") String username,
@QueryParam("password") String password){
User user = new User();
user.setId(users.size() +1);
user.setUsername(username);
user.setPassword(password);
users.put(user.getId(), user);
return new ArrayList<User>(users.values());
}
。功能
答案 0 :(得分:2)
使用volatile
时,getter函数对此没有任何帮助。
如果get_clock_ticks()
为external
(即在单独的模块中),则问题不同(也许这就是您所记得的)。
可以在正常程序流程之外(例如在ISR中)更改其值的某些内容应始终声明为volatile
。
答案 1 :(得分:1)
不要忘记,即使您当前编译声明get_clock_ticks的代码和使用它作为单独模块的代码,也许有一天您将使用链接时或跨模块优化。即使您使用的是getter函数,也要保持“volatile” - 在这种情况下,它不会对代码生成造成任何伤害,并使代码更正。
您没有提到的一件事是处理器的位大小。如果它无法在单个操作中读取32位值,则get_clock_ticks()有时会失败,因为读取不是原子的。