Processing Threads, Synchronization of Variables across threads!

edited February 2016 in Kinect

Hi all, hope someone can shed some light on this. This is my first time working with threads in processing I'm using a simple implementation of thread("somemethod"). Within somemethod() I have a globally declared boolean being altered but this is not being recognised by other functions in the main draw() loop?! simplified code below :)

simplified code shown in the post below.

Any suggestions would be greatly appreciated!

In a nutshell how do you get a variable (boolean) state change in one thread to affect the state of the same boolean in another thread? :)

Answers

  • Please format your code for the forum.

  • edited February 2016

    whoops, lets try that again..

    volatile boolean readyToCapture = false; 
    volatile boolean readyToStream = true; 
    volatile boolean pushToDetect = false;
    
    void setup() {
      // init some things here
    }
    
    void draw() {
      if (readyToStream == true) {
        RGBvideo = kinect.getVideoImage();
      }
      // Draw the PointCloud to the Screen
      if (readyToStream == true) {
        kinectPointCloud();
      } else { 
        capturedPointCloud();
      }
      if (readyToCapture == true) { 
        if (frameCount % 2 == 0) {
          thread("faceDetect"); //
          // ISSUE IS HERE! readyToStream is set to false in the faceDetect() 
          // method however this is not carried into the other methods in the 
          // primary draw loop?!
        }
      }
    
      if (pushToDetect == true) {
        thread("pushRequest"); 
        pushToDetect = false;
      }
    } 
    

    formating fixed by moderator

    this is a simplified version of the actual code.. please refer to the question above! thanks

  • edited February 2016

    ISSUE IS HERE! readyToStream is set to false in the faceDetect()...

    Wouldn't be much easier & safer to simply issue readyToStream = false; before thread("faceDetect");?

    You know, draw() is called back @ ~60 FPS. And while faceDetect() is busy executing its task, kinect.getVideoImage() & kinectPointCloud() can happen to be invoked in next draw() frame, while faceDetect() is still delaying readyToStream = false;! :-S

  • Unfortunately its not that simple.. The faceDetect method determines if a face is present and sets readyToStream to false and readyToCapture to false.. This happens inside the faceDetect() method.. So somehow I need to synchronize / track the boolean change happening across the other threads.. Hope I'm making sense!

  • Since the booleans are being set in another thread you can't be sure when it happens in tthe main thread. So in the faceDetect method readyToStream is set false but perhaps not in time for the next frame when it is tested again in lines 10 and 14

  • edited March 2016
    • Calling thread("") in draw() isn't my style at all. I've never done that yet! b-(
    • IMO, if we need some background task, we should create it once at the end of setup().
    • In order to keep it running indefinitely, we just need to wrap the whole code inside:
      while (true) {} or for ( ; ; ) {}.
    • From there, the thread("") can issue orders like a semaphore for the main "Animation" Thread.
    • You can check out an old OpenCV thread("") example I did below:
      https://forum.Processing.org/two/discussion/10654/getting-video-jitter-from-webcam-capture
  • Hey thanks everyone for your quick replies!

    Turns out the booleans were actually doing their job switching between threads and methods as the code currently stands! .. the "error" was being caused by where i'd placed a copy array statement i made... by passing the boolean..

    long story short.. i figured out the problem! :)

    but Iam curious.. if you did declare a thread in the setup, i.e. thread"someMethod".. how would you call it in the draw loop if you need the method to run intermittently? someMethod(); ? or while(true){someMethod();} or while(true){thread"someMethod";}

  • edited March 2016 Answer ✓

    ... how would you call it in the draw loop...

    • It's always working, so we don't call it! Most we can do is having some variable to coordinate its actions.
    • For example, we can issue readyToCapture == true from draw().
    • Then having the infinite thread("") function check for it and set it back to false.
    • And almost forgot, we need to use delay() on the thread("") function while it's idling. Lest we can get a fried CPU! :-SS
  • edited March 2016

    Hi all, sorry thought I'd ask a related question in here instead of starting a new post :)

    So i've got a separate thread running openCV's face detection (running at 12fps-ish) the main animation thread is at 60fps.

    The issue is, when I try write out info from the OpenCV thread into the main animation thread and try to use it.

    The animation thread drops to 12fps?!.. I know I'm missing some trick here..

    some pseudo code to illustrate my point.. (maybe not necessary but just incase)

        float faceX = 0;
        float faceY = 0;
        float faceWidth = 0;
        float faceHeight = 0;
    
        void setup(){
        // init some stuff here..  
        }
    
        void draw(){
    
        // some code to draw some rectangles when faces are detected..
        drawFaceRectangles();
    
        // run once every 4 frames 
        if(frameCount % 4 == 0){
        thread("faceDetect");
        }
    
        }
    
        void faceDetect(){
    
        // on face detect write out some face detection information into faceX, faceY,faceWidth,faceHeight.
    
    // This happens once every 4 frames..
    
        }
    
    
        void drawFaceRectangles(){
    
        // I am happy for the values to be updated once every 4 frames and have some lagg
    
    // this is where the main animation thread drops to 12fps because its using variables referenced in the openCV thread..
        rect(faceX,faceY,faceWidth,faceHeight);
        }
    

    I guess the question is how can I tell processing to get the current instance of the values instead of waiting for the next 4 frames.

    Thanks guys!

Sign In or Register to comment.