我想将以下内容传递给 c 中的函数:
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
Run Code Online (Sandbox Code Playgroud)
以下似乎工作得很好:
void ZeroRegister(unsigned long * _REG)
{
#define vReg (*((volatile unsigned long *)_REG))
vReg = 0;
}
Run Code Online (Sandbox Code Playgroud)
有更好的方法来编码吗?或者我的代码有缺陷?除了它生成的编译器警告之外。
所以我的问题本质上是,即使我使用 static 易失性 int 变量进行增量,我的一些数据也不会保持唯一,这将是我的目标(我对元素进行编号)。
public class Producer implements Runnable{
private String str;
private Fifo f;
private int i;
private static volatile int n=0;
public Producer(String str,int i,Fifo f) ....
public void run() {
try {
this.go();
} catch (InterruptedException e) {
;
}
}
void go() throws InterruptedException {
while(true) {
Thread.sleep(i);
int l=n++;
String k=str+" "+l+" ";
f.put(k);
System.out.println("produced "+str+" "+l+" "+System.currentTimeMillis()%100000);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题出在函数 go() 中。我对元素进行编号,我有多个 Producer 对象作为独立线程运行,但有时它们表现得好像不知道 n 是否已更新,所以我得到相同的索引。有任何想法吗?(我知道可能是什么问题,但我不知道如何解决它。)
volatile当多个并发线程读/写变量时需要修饰符。
是否有工具可以volatile自动检测缺少的修饰符,例如在 Android Studio 中?
算法:
for (Class c:allClasses) {
for (Field f:allFields) {
List<Method> allMethods = getCallHierarchy(field);
for (Method m:allMethods) {
List<Thread> threads = getCallingThreads();
if (threads.size() > 1) {
Log.w("Warning: field "+f+" is accessed by several threads.");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
测试算法的代码:
public class Foo {
private int a; //accessed by only one Thread - ok
private int b; //accessed by two Threads - show compiler warning
public static void main(String[] args) {
a = …Run Code Online (Sandbox Code Playgroud) 我有一个枚举,我想我可以缓存values().
enum MyEnum {
SOME;
private static volatile Set<MyEnum> values_;
public static Set<MyEnum> values_() {
Set<MyEnum> result = values_;
if (result == null) {
values_ = result = Collections.unmodifiableSet(EnumSet.allOf(MyEnum.class));
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了允许重复初始化的延迟初始化。
奏鸣曲也有volatile Set<MyEnum>部分抱怨。
SonaLint:使用线程安全类型;添加“易失性”不足以使该字段成为线程安全的。
https://rules.sonarsource.com/java/RSPEC-3077
我的代码有问题吗?
假设我在这样的循环中检查变量.
while( var )
;
Run Code Online (Sandbox Code Playgroud)
在这里,VAR必须申报volatile,如果程序是多线程和VAR被多个线程访问.这是一个众所周知的事实.但是,让我们说,我们有类似的东西.
while( var + 1 )
;
Run Code Online (Sandbox Code Playgroud)
这还能用volatile吗?我的意思是编译器可能缓存(var + 1)的值吗?换句话说,我问我们是否需要像下面这样编写代码,temp也是一个volatile变量,以确保编译器不会进行缓存.
while( temp )
temp = var + 1;
Run Code Online (Sandbox Code Playgroud) 我意识到我的例子一般不正确.但有趣的是找出它是如何工作的.
/* C/C++ (gcc-4.3.4) */
#include <stdio.h>
int main() {
/*volatile*/ int i = 5;
int j = 500;
int *p = &j;
printf( "%d %x\n", *p, p );
p++;
printf( "%d %x\n", *p, p ); // works correct with volatile (*p is 5)
//printf( "%d %x\n", *p, &i ); // works correct without volatile
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是某种优化吗?
UPDT 好的我得到了UB.我不希望别的别的.
但是,如果我有2个int vars,彼此相邻(见地址)为什么这个代码不起作用?
该volatile关键字告诉编译器不要优化带前缀的变量.变量可能在运行时由未知源(编译器不知道)可能由外部中断等改变.
还有其他优点volatile吗?是否volatile适用于从文件中读取?
我正在尝试看看volatile这里的工作方式。如果声明cc为volatile,则输出如下。我知道线程执行输出有时会有所不同,但是我读到的volatile内容与相同synchronized,那么为什么要获得此输出?如果我使用两个实例,Thread1那有关系吗?
2线程-0
2线程1
4线程1
3线程-0
5线程1
6线程-0
7线程1
8线程-0
9线程1
10线程-0
11线程1
12线程-0
public class Volexample {
int cc=0;
public static void main(String[] args) {
Volexample ve=new Volexample();
CountClass count =ve.new CountClass();
Thread1 t1=ve.new Thread1(count);
Thread2 t2=ve.new Thread2(count);
t1.start();
t2.start();
}
class Thread1 extends Thread{
CountClass count =new CountClass();
Thread1(CountClass count ){
this.count=count;
}
@Override
public void run() {
/*for(int i=0;i<=5;i++)
count.countUp();*/
for(int i=0;i<=5;i++){
cc++;
System.out.println(cc + Thread.currentThread().getName()); …Run Code Online (Sandbox Code Playgroud) 我有这个代码,像往常一样,变量"local"的值保持不变,因为它是一个const.
const int local = 10;
int *ptr = (int*)&local;
printf("Initial value of local : %d \n", local);
*ptr = 100;
printf("Modified value of local: %d \n", local);
Run Code Online (Sandbox Code Playgroud)
虽然,当我将local设置为const volatile时,它会将local的值更改为100.为什么?
const volatile int local = 10;
int *ptr = (int*)&local;
printf("Initial value of local : %d \n", local);
*ptr = 100;
printf("Modified value of local: %d \n", local);
Run Code Online (Sandbox Code Playgroud)
我理解的volatile的唯一含义是它阻止编译器对该变量进行优化,以防它的值必须由外部元素更改.但我无法弄清楚如何以及为什么volatile会覆盖const的功能.
编辑 - 从所有答案看来,我的代码是模糊的,任何输出都是不可预测的,因为我正在调用未定义的行为.
我知道这里有很多关于volatile的问题,但是我没有找到任何特定于这种情况的东西.我正在使用微控制器.我知道当我在ISR中修改一个全局变量并在我的main函数中读取它时,我必须使用volatile限定符.我也觉得非常适合记忆障碍,比赛条件等.
但是如果我只在主函数中写入一个全局变量(中断被禁用以强制执行原子写入)并且我正在我的ISR中读取和写入它.
为了给出一个明确的例子假设这个代码:
int state = 0;
ISR()
{
switch(state)
{
case 0:
//do something
state=nextState; //go to another state
break;
case 1:
//do something
state=nextState; //go to another state
break;
case 2:
//do something
state=nextState; //go to another state
break;
//...some more states
default:
state=0;
break;
}
}
main(void)
{
while(true)
{
//do lots of stuff
if(someCondition)
{
EnterCriticalSection(); //Disable IRQs and memorybarrier
//write to global shared variable state here!!!
state=0;
ExitCriticalSection(); //Enable IRQs again
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以必须在这里挥发吗? …