Archived

This forum has been archived. Please start a new discussion on GitHub.

Concurrent Threads "stealing" information

Hi everyone,

I'm developing a surveillance system for my grade and I must use Ice. After learning many documents, I earned a minimun function of my program.

A camera (client) have to pass a frame from a video to the server, and this have to segment it (by substract functions) and show it (using OpenCV).

The problem comes when I need multiples cameras sending information to different servers. Each client has his own server.

When I initialize a client/server thread, it runs well. Client opens a opencv window with the frame and server opens another windows with the segmented image. But when I initialize the second thread, with a different configuration (id, port) the first thread images continue showing on the second thread's window.

I tested with a simple program, a counter. I initialize the thread 1 who prints a counter with the port where the thread is running. When I initialize the thread 2, both threads print the same port.

10000 -> 1
10000 -> 2
10000 -> 3
10000 -> 4
10000 -> 5 //thread 2 starts
11000 -> 1
11000 -> 6
11000 -> 2
11000 -> 7
11000 -> 3
11000 -> 8
...

The problem is the same with OpenCV. Images wich should show in "window1", continue showing in "window2" after thread 2 begin.
Any idea?

Thank you very much and sorry for my english :)

Comments

  • bernard
    bernard Jupiter, FL
    Hi Carlos,

    Unfortunately I am not following your description. It could be a thread-safety problem with your code.

    Could you post a short example that reproduces this behavior? The shorter the better, and preferably without a dependency on third-party packages such as OpenCV.

    Cheers,
    Bernard
  • This is the code where I start the threads for the clients. It's the same for the servers. I create 1 thread for each client and 1 for each server with the same port/ip. Totally I create 4 threads(2 clients/2 servers).

    class CamThreads : public IceUtil::Thread{

    public:

    CamThreads(char direct[], char port[]){
    directorio=direct;
    puerto=port;
    }

    virtual void run(){
    Camara cliente;
    //cout<< "Estoy en el client thread " << directorio << " con el puerto " <<puerto << endl;
    cliente.run(directorio, puerto);
    }

    private:
    char* directorio;
    char* puerto;
    };



    int main(int argc, char *argv[]){

    vector<IceUtil::ThreadControl> threads;
    int i;

    for (i = 0; i < 2; ++i) {
    char directorio[200];
    char puerto[10];

    cout << "\n Directorio: ";
    cin >> directorio;
    cout << "\n Puerto: ";
    cin >> puerto;
    IceUtil::ThreadPtr t = new CamThreads(directorio, puerto);

    threads.push_back(t->start());
    }



    for (vector<IceUtil::ThreadControl>::iterator i = threads.begin(); i != threads.end(); ++i) {
    i->join();
    }


    return 0;

    }

    The code for cliente.run is:

    int run2(char directorio[], char puerto[]){
    std::string s(std::string(puerto) +":default -p "+std::string(puerto));
    Ice::CommunicatorPtr communicator; //Por ello tenemos que crear el Communicator
    communicator = Ice::initialize();
    Ice::ObjectPrx base = communicator->stringToProxy(s);

    Proyecto::ImageProviderPrx imagenPrx = ImageProviderPrx::checkedCast(base);
    cout << "Inicio thread ";
    cout << base->ice_getIdentity().name << " " << puerto << endl;
    itera(0,imagenPrx, puerto);
    cout << "Final thread ";
    cout << base->ice_getIdentity().name << " " << puerto << endl;
    communicator->waitForShutdown();
    if (communicator){
    communicator->destroy();
    }
    return 0;
    }

    And the function itera:

    void itera(int j, ImageProviderPrx proxy, char puerto[]){
    for(j;j<=100;j++){
    char port[10];
    strcpy(port, puerto);
    char aux[10];
    itoa(j,aux,10);
    strcat(port, " ");
    strcat(port, aux);
    cout << port << endl;
    proxy->pasaParam(port); //just pass the string to the server and server prints it
    Sleep(1000);
    }
    }

    When I begin the first thread, the server prints:

    10000 -> 1
    10000 -> 2
    10000 -> 3
    10000 -> 4
    10000 -> 5
    10000 -> 6
    ...

    When I begin the second thread during the execution of first thread, it prints:

    //thread 1 starts in port 10000
    10000 -> 1
    10000 -> 2
    10000 -> 3
    10000 -> 4
    //here thread 2 starts in port 11000
    11000 -> 1
    11000 -> 5 //this line should print 10000 -> 5, but thread 2 "steals" the port variable
    11000 -> 2
    11000 -> 6 //the same, this line should print 10000 -> 6
    11000 -> 3
    11000 -> 7
    ...

    When thread2 starts, both threads are running but it seems like thread2 works with the information of thread1.

    Could it be a problem of thread pool size? I have no idea, I'm really newbie in Ice.

    Thanks!
  • bernard
    bernard Jupiter, FL
    Hi Carlos,

    You're seeing an output from your server that you don't expect, and the only code you copied in your post in your client's code ... it's hard to guess where the bug is.

    If you have multiple threads calling cout / cerr concurrently (in your server), you may not get a very usable output. You should use a mutex to serialize all these calls.

    Then, in your client:
    - I highly recommend using something else than a port-number for your Ice object-id!
    - you should create a single Ice communicator, shared by all your threads, and no one communicator per thread
    (this has of course nothing to do with what your server prints).

    Best regards,
    Bernard