两个DispatchSourceTimers共享一个资源错误多线程任务 [英] two DispatchSourceTimers sharing one resource error, multithread task

查看:150
本文介绍了两个DispatchSourceTimers共享一个资源错误多线程任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须完成一个简单的任务-具有两个按钮和三个踏板的Singleview应用-

I have to make a simple task - singleview app with two buttons and three treads -

开始按钮:

创建线程T1-每3.0秒重复收集一次设备的GPS位置,并将结果(作为字符串)移交给T3.

create a thread T1 - the GPS location of the device is collected repeatedly every 3.0 seconds, and the results (as a string) are handed over to T3.

创建线程T2-每B秒重复收集一次设备电池的使用百分比,并将结果(作为字符串)移交给T3.

create w thread T2 - the percentage usage of the device's battery is collected repeatedly every B seconds, and the results (as a string) are handed over to T3.

T1和T2中的数据应存储在位置有限(maxData)的数组中. 在线程T3中,如果数组达到maxData,则应通过HTTP将数据发送到服务器(URL).然后清除数组

Data from T1 and T2 should be stored in array with limited positions (maxData). In Thread T3, if array reaches maxData data should be send to the server (URL) via HTTP. Then clear array

停止按钮-只需停止所有三个线程

STOP button - just stop all three threads

我对iOS线程一无所知.不幸的是,即使没有必要,App也必须使用线程.在我的上一个问题中,

I am a total noob in iOS threading. Unfortunately, App MUST use threads even if it is not necessary. In my previous question, Rob Napier suggested to use DispatchSourceTimers.

我已经接近找到合适的解决方案,但是……仍然是错误的.当我清除数组并发布时,来自DispatchSourceTimer 的单个数据丢失了.我猜想,这是 concurrentDataQueue.async(flags:.barrier)的错误,我不得不以某种方式阻止读取数组(?)

I'm close to find a proper solution, but sth is still wrong. When i clear array and post, single data from DispatchSourceTimer is LOST. I guess, that sth is wrong with concurrentDataQueue.async(flags: .barrier), and i have to block reading of array somehow (?)

BackgroundThreadTimer类只是DispatchSourceTimers的包装,该包装取自 中篇文章(RepeatingTimer)

Class BackgroundThreadTimer is just wrapper for DispatchSourceTimers taken from medium article(RepeatingTimer)

//partly Pseudocode
var counter = 0
var data = [String]()
var maxData = 5
var counterInt = 0

var concurrentDataQueue = DispatchQueue(label: "dataCleanAndPostQueue", attributes: .concurrent)

var timerLocalization = BackgroundThreadTimer(timeInterval: 2)
timerLocalization.eventHandler = {
    //do sth and receive String x with actual localization
    //...
    concurrentDataQueue.async(flags: .barrier) {
        appendAndPost(phoneInfo: String(counterInt) + ": " + x)
        counterInt += 1
    }
    
}

var timerBattery = BackgroundThreadTimer(timeInterval: 3)
timerBattery.eventHandler = {
    //do sth and receive String x with actual battery level
    //...
    concurrentDataQueue.async(flags: .barrier) {
        appendAndPost(phoneInfo: String(counterInt) + ": " + x)
        counterInt += 1
    }
    
}

func appendAndPost(phoneInfo: String) {
    if data.count < maxData {
        data.append(phoneInfo)
    } else {
        let arrayString = data.joined(separator: "; ")
        DispatchQueue.global(qos: .background).async {
            //post arrayString to http
            print(arrayString)
        }
        data = [String]()
    }
}

//when start pressed
timerLocalization.resume()
timerBattery.resume()

//when stop pressed
timerLocalization.suspend()
timerBattery.suspend()

某人可以帮忙吗?是我的 诊断正确吗?以及解决方法.

Could sb help? Is my diagnosis proper? And how to fix this.

推荐答案

appendAndPost中,仅当计数小于maxData时,才追加结果.

In appendAndPost, you are appending result only if the count is less than maxData.

但是,让我们想象一下,您在数组中已经有五个项目的地方调用了它.在这种情况下,您可以启动请求,但是您永远不会使用提供的值做任何事情.

But let’s imagine that you called this where you already had five items in the array. In that scenario, you start the request, but you’re never doing anything with the supplied value.

我建议无论如何都附加值,并在count达到阈值时发送:

I would advise appending the value regardless, and sending if the count hits the threshold:

func appendAndPost(phoneInfo: String) {
    data.append(phoneInfo)

    if data.count >= maxData {
        // create your request and send it

        ...

        // reset `data`

        data = []
    }
}

这篇关于两个DispatchSourceTimers共享一个资源错误多线程任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆