在python

时间:2018-03-30 16:11:50

标签: python multithreading python-multithreading

我一直在运行多个线程(通过"符号"下面)但遇到了一个奇怪的问题,根据首先处理的内容,似乎存在潜在的内存泄漏。我认为问题是由于我在每个线程中使用相同的字段名称/数组名称。

下面是我正在运行的为数组赋值的代码示例:

for i in range(level+1):
    accounting_price[i] = yahoo_prices[j]['accg'][i][0]

它工作正常,但当我查询多个"符号"并为每个符号运行一个主题,我有时会得到符号A' accounting_price [i]"在符号C中返回,反之亦然。不确定这可能是从一个线程到另一个线程的内存泄漏,但我唯一的快速解决方案是制作" account_price [i]"每个符号都是唯一的。如果我实施以下内容会是正确的吗?

symbol = "AAPL"
d = {}
for i in range(level+1):
    d['accounting_price_{}'.format(symbol)][i] = yahoo_prices[j]['accg'][i][0]

当我运行它时,我收到一个错误。

我非常感谢有关如何为每个线程动态创建唯一数组的解决方案。或者,解决内存泄漏问题"。

谢谢!

2 个答案:

答案 0 :(得分:0)

如果你认为这里有一场比赛导致对dict的写入冲突,那么使用锁定是解决问题的最好方法,如果你是对的话,可能是最好的解决方案。

我应该指出,一般来说,由于全局解释器锁,对dict和list成员的简单赋值已经是线程安全的。但要证明你的案件是“一般”案件之一并不总是容易的。

无论如何,如果你有一个可共享的可变全局对象,你需要有一个与它一起共享的全局锁,你需要围绕对象的每次访问(读和写)获取锁。 p>

如果可能的话,你应该使用with语句来确保不可能放弃锁定(这可能导致其他线程永远阻塞等待同一个锁)。

确保您不进行任何昂贵的工作(例如下载和解析网页)并获得锁定(这可能会导致所有线程最终序列化而不是并行运行)也很重要。

因此,在创建accounting_info的全局级别,创建相应的锁:

accounting_info = […etc.…]
accounting_info_lock = threading.Lock()

然后,在线程内,无论你在哪里使用它:

with accounting_price_lock:
    setup_info = accounting_price[...]

yahoo_prices = do_expensive_stuff(setup_info)

with accounting_price_lock:
    for i in range(level+1):
        accounting_price[i] = yahoo_prices[j]['accg'][i][0]

如果最终经常有大量读取和少量写入,这可能会导致过多和不必要的争用,但您可以通过用读写锁替换通用锁来解决这个问题。它们总的来说有点慢,但如果一堆线程想要并行读取,速度要快得多。

答案 1 :(得分:-2)

错误大概是KeyError,对吧?这是因为当只有一个级别存在时,您将两个级别编入索引。试试这个:

 private MediaPlayer mediaPlayer;
private TextView textView;
private SensorManager sensorManager;
private Sensor accelerometerSensor;
private float maxf;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) this.findViewById(R.id.textView);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_UI);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
            return;
        }
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
        float f =  Math.round(Math.abs(x*x + y*y + z*z));
        if (f>maxf ){ maxf =f;}
        StringBuilder sb = new StringBuilder();
        sb.append("forrce:").append(f).append("\n");
        sb.append("MaxForce:").append(maxf).append("\n");
        textView.setText(sb.toString());

      if (maxf>150) {
            mediaPlayer = MediaPlayer.create(this, R.raw.b);
            mediaPlayer.start();
            maxf=1;
        }
   }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

            }