0
votes

Swift Semaphore Command-Line-Tool-Tool Project Attendez que le groupe fini

semble ne pas attendre la fin du groupe xxx

Je m'attends à la sortie de Nd p = 1000000 t.count = 1000000

Je peux obtenir ce résultat si i i i de stade // semiaphoreend.Wait ()

, mais la sortie réelle est

Fin p = 999871 t.count = 999881

Autre problème: T.compte! = P

avec le groupe Je m'attends à la fin de toutes tâches. Pourquoi je dois me défendre // SEMAPHOREEND.WAIT ()?

Merci

Projet ici pour le téléchargement: https://github.com/fredongithub/semplore_to_modify_1


8 commentaires

Vous avez utilisé DISPATCHQUATE.GLOBAL (). ASYNC, le bloc est exécuté sur la file d'attente principale de manière asynchrone, de sorte que le groupe_2 entre alors soudainement la sortie et votre bloc est exécuté de manière asynchrone.


J'ai commenté tout pour le code de boucle // pour _ in 0 .. et efficacement, il passe le groupe_2 attendre pour imprimer le tableau


Désolé, c'est horrible code. Veuillez apprendre à gérer le traitement des données asynchrones. DIT, ne demandez pas . Et pour exécuter un code asynchrone dans une CLI, vous avez besoin d'un sellogue de toute façon.


Cli = interface de ligne de commande. Pensez-vous que je reçois un runloop si je marche // tandis que (p! = Max) {// USLEeP (1_00_000) // Imprimer ("P =", P) //}?


Non, vous devez démarrer et arrêter explicitement l'alunloop.


Je mets ci-dessous une première solution avec Runloop


J'aimerais que votre Vadian nous dise de quoi préférez-vous de ces 2 solutions d'exécution. Un de fondation de base> cfrunloop et une autre de Fondation> Processus et threads> Runloop . Merci


Quelqu'un peut expliquer le meilleur de ces 2 solutions d'exécution?


3 Réponses :


0
votes

Solution pour ce problème:

J'ai mis en groupe_2.Lave () dans un mauvais endroit. Comme ici En attente jusqu'à la fin de la tâche && GCD Expliquez et d'autres comme 2. DISPATCHGROUP Vous devez le mettre dans la fonction ASYNC dans son achèvement xxx

avec cette solution, je n'ai pas besoin de tester si p == max pour déverrouiller le Impression finale du tableau (Semaphoreend.signal ())

Cependant, il existe une bonne note de Vadian "Non, vous devez démarrer et arrêter l'exécution explicitement."

Je cherche cette implémentation, c'est incroyable, sortant


0 commentaires

0
votes

Une autre solution pour ce problème (sans groupe d'attente): Selon le Conseil de Vadian

voir Comment sortir d'un runloop? , Fondation de base> CFRONLOOP P>

let oneSem_1 = DispatchSemaphore(value: 1)
let semaphore = DispatchSemaphore(value: 4)
var p=0
var t:[Int]=[]
let MAX=100_000
#if DEBUG
print("DEBUG")
// Store a reference to the current run loop
let runLoop = CFRunLoopGetCurrent()
#endif

func task(){
    //sleep(1)
    oneSem_1.wait()
    p+=1
    t.append(p)//ressource critique, sinon pas rempli à fond
    if p == MAX{
        #if DEBUG
        print("CFRunLoopStop(runLoop)")
        CFRunLoopStop(runLoop)
        #else
        DispatchQueue.main.async{
            print("CFRunLoopStop(CFRunLoopGetCurrent())")
            CFRunLoopStop(CFRunLoopGetCurrent())
        }
        #endif
    }
    oneSem_1.signal()
}
for _ in 0..<MAX {
    DispatchQueue.global().async{
        semaphore.wait()
//        print("wake up")
        task()
//        print("end")
        semaphore.signal()
    }
}
// Start run loop after work has been started
print("start")
CFRunLoopRun()
print("END   p=\(p)  t.count=\(t.count)")


0 commentaires

0
votes

Encore une fois une autre solution pour ce problème (sans groupe d'attente)

Utilisation de processus et de threads Apple> Runloop :: Selon le Conseil de Vadian p>

voir attendre jusqu'à la fin de la tâche A >, Fundation> Processus et threads> Runloop P>

// Store a reference to the current run loop
var shouldKeepRunning = true
let runLoop = RunLoop.current
func task(){
    //sleep(1)
    oneSem_1.wait()
    p+=1
    t.append(p)//ressource critique, sinon pas rempli à fond
    if p == MAX{
        print("p == MAX")
//        shouldKeepRunning = false//BUG!!
        DispatchQueue.main.async{//METTRE CECI
            shouldKeepRunning = false
        }
    }
    oneSem_1.signal()
}
for _ in 0..<MAX {
    DispatchQueue.global().async{
        semaphore.wait()
        //print("wake up")
        task()
        //print("end")
        semaphore.signal()
    }
}
// Start run loop after work has been started
print("start")
while shouldKeepRunning  && runLoop.run(mode: .default, before: .distantFuture)
{
    print("WROTE ONLY ONCE")

}
print("END   p=\(p)  t.count=\(t.count)")


0 commentaires