Thread: Aargh... evil static

  1. #1
    The larch
    Join Date
    May 2006
    Posts
    3,573

    Aargh... evil static

    I'm trying to convert a single-threaded app to use multithreading (first time for me) and I immediately got punished for my sloppiness.

    Code:
    #include <iostream>
    
    struct A
    {
        int n;
        A(int n): n(n) {}
        void foo() {
            static int num = n;
            std::cout << num << '\n';
        }
    };
    
    int main()
    {
        A a(10), b(20);
        a.foo();
        b.foo();
    }
    Such statics are shared between objects which I thought would be completely independent but now that I have multiple threads it turns out they provide a back door to mess up each others internal state. (In singlethreading everything is OK, since the static has to remain stable only as long as the function call lasts.) Glad I was at least using asserts to catch problems with the internal state.

    Guess I'll have to make them regular members of the class (or local variables).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Haha, I thought you fried your latest graphics card or something
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Actually they were motived from an attempt at premature optimization.

    I needed a temporary vector in some functions, but I thought I'd be clever and not let them release the memory between the function calls:
    Code:
         static vector<int> vec;
         vec.clear();
         //fill up and use
    Guess, this is an antipattern after all.

    For now I just removed static and run a test to see if this tricks makes any difference in performance.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yeah, as you know, if 2 or more threads accesses the same object (or if you create new objects that contains static members that are are used), you have to do locking to avoid a data race.
    Multi-threading is a pain, I give you that.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Nah, the performance difference after simply removing static is only about 0.1 ms per 8 ms, so there's no reason to start messing with locks (I use locks to protect accesses to the vector that contain the results of the jobs). I'll have to see how the new multithreading version runs on a slower machine before I start to make radical changes.

    Actually I just discovered that I had failed to apply an optimization (changing the value of a single constant) to part of the program, that just gained me about 1 ms per 8 ms job.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I did an experiment with locks myself.
    With time critical code, the code ran 5s (I think the time was about 4s vs 9s or so) slower with locks. And that was only when one thread was locking, so locking is not always optimal!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Since this is first time multithreading for me, I decided to keep to the count of processes low.

    The main process obtains a resource (pops from a vector of queues) and the background process periodically checks the size of the queues and pushes more if needed. If the main process still runs out of the resource (when user keeps pressing the "New" button like crazy), it simply blocks to create the resource by itself.

    Initially I tried to launch an "emergency thread" in such cases and then let the main thread check the queues but that became messy (couldn't even figure out a good strategy to seed random number generators) and the whole program would lock up sometimes (perhaps because of the statics again).

    ----------
    I hope that my understanding of locks is correct: the main process creates a lock (wxCriticalSection in my case, from wxWidgets) and passes a reference to any threads it creates. Then all accesses to a shared resource must be surrounded by a call to enter() and leave() of the section (or using wxCriticalSectionLocker) and in the meantime other threads have to stop when they reach a critical section and wait until the other thread has left from the critical section.
    Last edited by anon; 01-12-2008 at 12:41 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. seg fault at vectornew
    By tytelizgal in forum C Programming
    Replies: 2
    Last Post: 10-25-2008, 01:22 PM
  3. uploading file to http server via multipart form data
    By Dynamo in forum C++ Programming
    Replies: 1
    Last Post: 09-03-2008, 04:36 AM
  4. LNK2001 ERROR!!! need help
    By lifeafterdeath in forum C++ Programming
    Replies: 7
    Last Post: 05-27-2008, 05:05 PM
  5. get keyboard and mouse events
    By ratte in forum Linux Programming
    Replies: 10
    Last Post: 11-17-2007, 05:42 PM