3 Stimmen

javascript kritische Abschnitte oder Semaphor-Problem

function myobj(){
  var gup=this;
  this.lastindex=-1;
  this.criticalSectionInTimer=0;
  this.updateTimer;

  this.start = function(l){
      if((typeof this.updateTimer)=="number"){
        clearInterval ( this.updateTimer );
      }
      this.updateTimer=setInterval(function() {gup.getMessages();} , 30);
    }

    this.stop= function(){
      if((typeof this.updateTimer)=="number"){
        clearInterval ( this.updateTimer );
      }  
    }

  this.addUpdate(i){
    //some code
  }

  this.rrrrnr=0;

  this.getMessages = function (){
    if(this.criticalSection==0){
       this.criticalSection=1;
      this.rrrrnr++;
      console.log("in critical section"+this.rrrrnr);
         var url="getmessages.php?lastindex="+this.lastindex;
         $.getJSON(url,
             function(data){
              gup.lastindex=data.lastindex;
              $.each(data.updates, function(i,item){
                gup.addUpdate(item);
              });
           }
         );
       console.log("out critical section"+this.rrrrnr);
       this.criticalSection=0;
    }
  }

}

var m= new myobj();
myobj.start();

Ich habe den Code von oben. Ich habe eine Hauptschleife, die Updates in einem bestimmten Zeitintervall macht. Das Problem ist, dass ich erkannt habe, dass es in den "kritischen Abschnitt" gelangt, den ich durch die Variable this.criticalSection abgegrenzt habe.

Von Firebug erhalte ich die Meldungen "in critical section" + index und "out critical section" +index in der richtigen Reihenfolge, aber die Ajax-Anfrage wird noch verarbeitet. Aber ich bekomme Anfrage mit dem gleichen Index und ich weiß wirklich nicht, wo für das Problem zu suchen.

Gibt es irgendwelche Buildin-Funktionen für Semaphoren oder kritische Abschnitte in Javascript?

2voto

seelmobile Punkte 126

Es gibt keine Semaphoren oder kritische Abschnitte, da JavaScript single-threaded ist. Der Ajax-Aufruf, den Sie tätigen, ist asynchron, d.h. er löst die Anfrage aus und geht dann fröhlich weiter und verlässt Ihren kritischen Abschnitt. Wie andere erwähnt haben, ist eine einfache Lösung, um die Anforderung synchron zu machen, aber das besiegt den Zweck von Ajax.

Wenn man sich Ihren Code ansieht, scheint es, als ob Sie versuchen, in regelmäßigen Abständen Aktualisierungen zu erhalten. Wenn dies der Fall ist, warum nicht die nächste Aktualisierung im Callback der Ajax-Anfrage planen?

this.getMessages = function (){
    var url="getmessages.php?lastindex="+this.lastindex;
    $.getJSON(url,
        function(data){
            gup.lastindex=data.lastindex;
            $.each(data.updates, function(i,item){
                gup.addUpdate(item);
            });
  gup.updateTimer=setTimeout(gup.getMessages, 30);
        }
    );

}

Dies würde die Notwendigkeit für Semaphoren beseitigen und entspricht eher der ereignisgesteuerten Natur von JavaScript. Der Nachteil ist, dass die Aktualisierungen nicht bei genau Intervalle. Außerdem scheinen 30 Millisekunden ein extrem kurzes Intervall zu sein.

0voto

MANCHUCK Punkte 2297

JQuery sendet AJAX standardmäßig asynchron. Anstatt zu tun getJSON versuchen:

$.ajax({
  dataType: 'json',
  url:  url,
  type: 'GET',
  async: false,
  success: function(data){
              gup.lastindex=data.lastindex;
              $.each(data.updates, function(i,item){
                gup.addUpdate(item);
              });
});

0voto

Johnco Punkte 3889

Das Problem ist recht einfach.

Sie verwenden AJAX, das per Definition asynchron ist. Das heißt, Sie führen $.getJSON aus, und die JS wird fortfahren und den kritischen Abschnitt verlassen, während die Anfrage verarbeitet wird. Daher können mehrere Aufrufe von getMessages durchgeführt werden, bevor die erste Anforderung abgeschlossen ist.

Es scheint, dass Sie beabsichtigen, dass ein solcher getJSON-Aufruf NICHT asynchron ist und innerhalb des kritischen Abschnitts blockiert wird, bis er endet. Um dies zu tun, müssen Sie die async-Eigenschaft auf false, etwas in den Zeilen zu setzen:

$.ajax({
  dataType: 'json',
  url:  "getmessages.php?lastindex="+this.lastindex,
  type: 'GET',
  async: false,
  success: function(data){
      gup.lastindex=data.lastindex;
      $.each(data.updates, function(i,item){
          gup.addUpdate(item);
      });
});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X