Thread: Multithreading

  1. #1
    Registered User Cela's Avatar
    Join Date
    Jan 2003
    Posts
    362

    Multithreading

    I don't see the use of threads in practice. Everything I've read states that threads allow two different operations to appear to happen at the same time. But every time I've tried to get that to happen it doesn't do anything special. For example, say I want to write a simple test for threads that shares two loops.

    Thread 1: FOO
    Thread 2: BAR
    Thread 1: FOO
    Thread 2: BAR
    Thread 1: FOO
    Thread 2: BAR
    Thread 1: FOO
    Thread 2: BAR
    Thread 1: FOO
    Thread 2: BAR

    This is what I expect when someone says synchronized execution. But all of my tries with _beginthread and _endthread end up like this.

    Thread 1: FOO
    Thread 1: FOO
    Thread 1: FOO
    Thread 1: FOO
    Thread 1: FOO
    Thread 2: BAR
    Thread 2: BAR
    Thread 2: BAR
    Thread 2: BAR
    Thread 2: BAR

    I don't need threads to do that. So I'm obviously missing something big, can someone show me how to do what I want using threads? I've read a lot on MSDN but that's not really much help.
    *Cela*

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    You probably have to adjust the thread priority, can't say for sure, though without seeing your code.

    Here is an old post with some code. Here's an old library I posted a while back, not very useful, codewise, but the lib's easy to use, anyway.

    Threads are quite useful. Imagine creating animation without it, etc...not a pretty picture.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> But all of my tries with _beginthread and _endthread end up like this.

    Obviously I cant' see your code, but if those two thread functions are really simple, it is quite possible that the first thread has finished executing before the second thread has been established.

    Try making your loops longer, and possibly add a small random sleep() into each iteration.

    If none of that makes sense, post your code.

    >>> You probably have to adjust the thread priority

    I would doubt that. If you throw two threads from the same process, they will have the same thread priority, altering one with respect to the other is more likely to produce the second, undesired result.

    >>> show me how to do what I want

    Not without knowing what it is you want to do!
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  4. #4
    Registered User Cela's Avatar
    Join Date
    Jan 2003
    Posts
    362
    >>Not without knowing what it is you want to do!
    My first post explained what I want to do, this is how I'm trying to do it.
    Code:
    #include <process.h>
    #include <stdio.h>
    
    void foo(void *no_op)
    {
      int i = 0;
    
      no_op;
    
      for (i = 0; i < 5; i++)
      {
        printf("Thread 1: FOO\n");
      }
    }
    
    void bar(void *no_op)
    {
      int i = 0;
    
      no_op;
    
      for (i = 0; i < 5; i++)
      {
        printf("Thread 2: BAR\n");
      }
    }
    
    int main(void)
    {
      _beginthread(foo, 0, 0);
      _beginthread(bar, 0, 0);
    
      _endthread();
    
      return 0;
    }
    >>it is quite possible that the first thread has finished executing before the second thread has been established.
    If the threads are executed in order then what's the point? Why not just do whatever you're doing in order and forget about threads altogether? I'm under the impression that if I have two threads at the same time, they'll do a little bit of work and then let the other thread do a little bit until nothing is left.
    *Cela*

  5. #5
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> If the threads are executed in order then what's the point?

    You miss my point, the threads are started in order because you call beginthread once, then again. What I am saying, is with thread functions as small as those, the thread spun by the first call to beginthread has finished executing before the second call to beginthread has spun the thread.

    >>> I'm under the impression that if I have two threads at the same time, they'll do a little bit of work and then let the other thread do a little bit until nothing is left.

    That's exactly right, but you are not seeing it with your example. Set the loop counters right up, or, as I said, introduce a short sleep() into your loops.

    Code:
    void bar(void *no_op)
    {
      int i = 0;
    
      no_op;
    
      for (i = 0; i < 5; i++)
      {
        printf("Thread 2: BAR\n");
        sleep(1000);
      }
    }
    You also need to review the use of endthread(), how you are doing it now is incorrect. endthread() is a routine you use inside thread functions, but in this case, it is not necessary since the thread exits when your thread function returns.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  6. #6
    Registered User Cela's Avatar
    Join Date
    Jan 2003
    Posts
    362
    >>but you are not seeing it with your example
    Wonderful! It works as I expected now that I've added a 1 second sleep.

    >>it is not necessary since the thread exits when your thread function returns.
    So I can just let the function return and the thread is terminated automatically? If so would it be better to say what I mean?
    Code:
    void bar(void *no_op)
    {
      int i = 0;
    
      no_op;
    
      for (i = 0; i < 5; i++)
      {
        printf("Thread 2: BAR\n");
        Sleep(1000);
      }
    
      _endthread();
    }
    *Cela*

  7. #7
    He's just saying get rid of the _endthread() in the MAIN(), since each fxn calls the _endthread() before it returns - it's redundant.

    >> If so would it be better to say what I mean?
    I don't know what u mean or are asking?

    This is more C++, I think as in Windows u use CreateThread() to create a thread.
    My Avatar says: "Stay in School"

    Rocco is the Boy!
    "SHUT YOUR LIPS..."

  8. #8
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by OneStiffRod
    This is more C++, I think as in Windows u use CreateThread() to create a thread.
    No....beginthread (and beginthreadex for that matter) both call CreateThread..... these functions ensure that the correct multithreaded libraries are linked and makes sure that each thread has its own global buffers for some function calls (ie the C std function ctime().....)

    Both are fully acceptable for C or C++

  9. #9
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> I think as in Windows u use CreateThread() to create a thread.

    CreateThread() has, in the past, been deprecated because it can cause small memory leaks in Win32 programs which use the standard library. There is still considerable debate on this subject, I am not sure this is an issue any longer, but to be safe, it's use is avoided by most Win32 programmers I know.

    _beginthread() and _beginthreadex() do not have this problem, ( the name _beginthreadex() is somewhat compiler dependent, Borland for example, used to call it _beginthreadNT()).

    *** EDIT ***

    Bit of multithreading there Fordy!
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  10. #10
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    Hmm, can't you use a critical section or semaphore to mediate between the threads? Okay, I don't know what I'm talking about (I've read about multithreading, but never used it) but I believe what I've mentioned is used for handling memory shared between threads...

    I'll shut up now.

  11. #11
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> critical section or semaphore

    There are a number of constructions you can use for thread synchronisation - those are two. Both of them can be used to prevent one thread screwing around with common memory at an inopportune moment.

    Cela will find that his simple program will fail soon! The thing with threads is that they can be interupted for another one to start at any time, including part way through a printf()!

    FOO
    BAR
    FBAR
    OO
    BAFOO
    R

    and so on. A critical section, for example, can stop that.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  12. #12
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Here's a quick Demo of a critical section...you dont have to use my class method.....but I like to......

    Code:
    #include <windows.h>
    #include <process.h>
    #include <stdio.h>
    
    class CS_{
    	CRITICAL_SECTION cs;
    public:
    	CS_(){InitializeCriticalSection(&cs);}
    	~CS_(){DeleteCriticalSection(&cs);}
    	void Enter(){EnterCriticalSection(&cs);}
    	void Leave(){LeaveCriticalSection(&cs);}
    }CS;
    
    void foo(void *no_op)
    {
      
    	int i = 0;
    
    	for (i = 0; i < 50; i++)
    	{
    		CS.Enter();		
    		printf("Thread 1: FOO\n");
    		CS.Leave();
    	}
    }
    
    void bar(void *no_op)
    {
    	int i = 0;
    
    	for (i = 0; i < 50; i++)
    	{
    		CS.Enter();		
    		printf("Thread 2: BAR\n");
    		CS.Leave();
    	}
    }
    
    int main(void)
    {
    	UINT hHandles[2];
    	
    	hHandles[0] = _beginthread(foo, 0, 0);
    	hHandles[1] = _beginthread(bar, 0, 0);
    
    	WaitForMultipleObjects(2,(CONST HANDLE*)(&hHandles),
    		TRUE,INFINITE);
    
    	return 0;
    }
    Also...removing the _endthread() from main would have stopped you app working....._endthread() was trying to stop your primary thread and whatever confusion that was causing was allowing the other threads to complete....without the _endthread() it was finishing the primary thread after the creation of the threads..therefore killing them before they could action......use one of the WaitFor##### APIs to stall the primary thread and allow the child threads to terminate naturally (as above)


    <edit>Oh...and its unlikely you will see the direct benefit of a critical sec in my example...though its certianly safer and will avoid the problem adrian stated..its use is far more obvious if you are manipulation memory....like say a link list with multiple threads accessing data at the same time......imagine 1 thread reading a node as another is deleting it - bound to cause bugs! </edit>

  13. #13
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    Don't give it all away Fordy, people learn better if they have seen the problem!
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  14. #14
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by adrianxw
    Don't give it all away Fordy, people learn better if they have seen the problem!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multithreading (flag stopping a thread, ring buffer) volatile
    By ShwangShwing in forum C Programming
    Replies: 3
    Last Post: 05-19-2009, 07:27 AM
  2. multithreading in C++
    By manzoor in forum C++ Programming
    Replies: 19
    Last Post: 11-28-2008, 12:20 PM
  3. Question on Multithreading
    By ronan_40060 in forum C Programming
    Replies: 1
    Last Post: 08-23-2006, 07:58 AM
  4. Client/Server and Multithreading
    By osal in forum Windows Programming
    Replies: 2
    Last Post: 07-17-2004, 03:53 AM
  5. Multithreading
    By JaWiB in forum Game Programming
    Replies: 7
    Last Post: 08-24-2003, 09:28 PM