Richiamo delle funzioni di blocco ed esecuzione del codice quando il risultato è pronto, ma senza richiamate

-2

Sto progettando un'applicazione che ha alcune funzionalità di scripting: l'applicazione host può chiamare gli script per eseguire alcune operazioni quando si verificano alcuni eventi. Per semplificare e agevolare i principianti, c'è un singolo thread per tutto: questo significa che se lo script chiama qualcosa che blocca, l'intera applicazione si blocca. Quindi, uso callback o polling per aspettare che un risultato di una chiamata di blocco sia pronto. Ciò che è brutto in questo approccio, è che una funzione che capita di chiamare una funzione di blocco, deve essere divisa in parti. Per il polling, avrei

function do something part 1
    blabla
    launch something lengthy
    schedule do something part 2
end

function do something part 2
    if result not ready then schedule do something part 2
    use result
    blabla
end

I callback sono solo leggermente migliori:

function do something
    blabla
    launch something lengthy, when done call callback
end

function callback
    use result
    blabla 
end

Se uno ha diverse chiamate di blocco e ognuna dipende dal risultato del precedente, il codice diventa più brutto e brutto. Quello che sto cercando è per qualche linguaggio di programmazione che abbia un supporto integrato per questo modello. Qualcosa come

function do something
    blabla
    launch something lengthy
    when done:    //fictional keyword
    use result
    blabla
    ....          //more and more blocking calls
end

Naturalmente se ci sono soluzioni migliori sono lieto di ascoltare.

    
posta Lorenzo Pistone 21.03.2013 - 23:36
fonte

2 risposte

1

What I'm looking for is for some programming language that have some builtin support for this pattern.

Non li hanno tutti adesso? ;)

Ne conosco due, funzionano tutti allo stesso modo: lanciare una funzione in parallelo, possibilmente su un thread diverso, e ottenere il risultato in seguito:

C # async

var task = BlockingFunction(arg);
// ...later...
var result = await task;

C ++ std :: async

auto handle = std::async(std::launch::async, blocking_function, arg);
// ...later...
auto result = handle.get();
    
risposta data 21.03.2013 - 23:52
fonte
0

Java ha qualcosa chiamato CountDownLatch, che dovrebbe fare ciò che stai cercando. Da JavaDoc per esso

 class Driver { // ...
   void main() throws InterruptedException {
     CountDownLatch startSignal = new CountDownLatch(1);
     CountDownLatch doneSignal = new CountDownLatch(N);

     for (int i = 0; i < N; ++i) // create and start threads
       new Thread(new Worker(startSignal, doneSignal)).start();

     doSomethingElse();            // don't let run yet
     startSignal.countDown();      // let all threads proceed
     doSomethingElse();
     doneSignal.await();           // wait for all to finish
   }
 }

 class Worker implements Runnable {
   private final CountDownLatch startSignal;
   private final CountDownLatch doneSignal;
   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
      this.startSignal = startSignal;
      this.doneSignal = doneSignal;
   }
   public void run() {
      try {
        startSignal.await();
        doWork();
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

L'idea di base è che puoi configurare il Latch affinché smetta di progredire fino al suo conto alla rovescia fino a 0. Una volta raggiunto lo 0, i thread in attesa continuano.

    
risposta data 22.03.2013 - 00:31
fonte

Leggi altre domande sui tag