_beginthread

Jan 15, 2009 at 7:12pm
Hi!

I'd like to know how to use _beginthread and _endthread to create a new parallel process.

I have to put the "read_audio" process running on background until a "ctrl_signal" comes, and so I create the "create_read_audio_process" thread to call the "read_audio" from that (in a buckle). The matter is that I have to pass 3 parameters to "read_audio" and so, I need these 3 parameters in the _beginthread function, and I do not know how to do it. Somebody knows how to solve it?

Thanks a lot.

Here is my code:

/*************************************************************/

#include <process.h>

int open_audio(audio_array*); // The prototypes
void create_read_audio_process(????);
int read_audio(short*, audio_array*);
int close_audio(audio_array*);

int main(short *samples, short *ctrl_signal)
{
audio_array aa; // audio_array is a structure

open_audio(&aa);
_beginthread(create_read_audio_process, 0, ????);
close_audio(&aa);

return 0;
}

void create_read_audio_process(???)
{
while(*ctrl_signal == 0)
{
read_audio(samples, &aa); // Function to read audio
}

_endthread();
}

/************************************************************/

Thanks a lot again,

Xagutxu


Jan 15, 2009 at 7:15pm
I'd suggest you read some theory on multi-threaded development. There is A LOT more to it than just putting in a begin and end thread call.

One you go to multi-threaded development you have to be very careful with memory access. Having multiple threads accessing the same memory concurrently becomes dangerous and causes bugs in software.

Once your ready to try threading. I'd suggest utilizing the Boost threading library. http://www.boost.org/doc/libs/1_35_0
Jan 15, 2009 at 8:20pm
Hello, Zatita:

You are ok when you say I would have to learn more about threads, but the fact is that I only want to use 2 processes. One will fill a buffer with data (asynchronously) and will active a parameter to indicate that a buffer block is ready to be read, and the other one will read these blocks, So, I thought that I will not have problems with memory access (or am I wrong...?). In this case, it is not enough starting and ending a thread in the way I have explained?

Thank you, and correct me if I am wrong, please.

Xagutxu
Jan 15, 2009 at 8:26pm
If your going to have 2 threads. And 1 thread won't do anything til the first thread is finished then this is not a threading problem. There is nothing gained, and no point in having the problem threaded.

Threading is only useful when you want 2 things to happen concurrently.
Jan 15, 2009 at 8:55pm
How will your worker thread indicate that the buffer is full so the other can begin to read it? This is a classic concurrency problem.
Jan 16, 2009 at 8:26am
I think you have not understood, Zaita. A thread will be reading the audio card continuously, and each time it fills a block, a the value of a variable will be changed. The other thread will sometimes check the value of this variable, and depending on its value, it will do one thing or other thing. Meanwhile, the first thread continues filling the buffers.

Going back to the initial question, is it possible to pass more than one parameter to the function _beginthread?

Thank you for answering me,

Xagutxu
Jan 19, 2009 at 10:44am
_beginthread takes one parameter. But you use it to pass a pointer to a structure with many fields.

The code below illustrates the point. It's not seen a compiler, so ...

Also, I've used _beginthreadex rather than _beginthread, but as someone mentioned in another thread, you may want to use something from a thread library (such as Boost), but you have to suffer the drawbacks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
struct Params
{
    int param1;
    long long param2;
    std::string param3;
};

int func(void *p)
{
    if (Params *params = reinterpret_cast<Params*>(p))
    {
        // ...
    }

    _endthreadex();
}

void dostuff()
{
    Params params;
    // fill in params

    unsigned id;
    unsigned threadid = _beginthreadex(0, 0, func, &params, 0, &id);
    // ...
    CloseHandle(threadid);
}

Last edited on Jan 19, 2009 at 1:11pm
Jan 19, 2009 at 6:57pm
I also highly suggest you read some tutorials on critical sections, mutexes and variable locking. Otherwise your going to end up with undefined behaviour very quickly.
Jan 20, 2009 at 12:46am
1
2
3
4
5
6
7
8
9
10
void dostuff()
{
    Params params;
    // fill in params

    unsigned id;
    unsigned threadid = _beginthreadex(0, 0, func, &params, 0, &id);
    // ...
    CloseHandle(threadid);
}


its a bit risky to do like this, the reason for this is that dostuff can exit before the thread ends making params invalid.

one way around it is to create a copy of the argument in your thread function or to post the data as a message to the thread, that way you have the mechanics to update the thread parameters during run-time.

N.B.: CloseHandle doesn't terminate the thread
Last edited on Jan 20, 2009 at 12:50am
Jan 20, 2009 at 12:58am
to OP:

1
2
3
4
5
6
7
8
9
10
int main(short *samples, short *ctrl_signal)
{
audio_array aa; // audio_array is a structure

open_audio(&aa);
_beginthread(create_read_audio_process, 0, ????);
close_audio(&aa);

return 0;
}


Unfortunately it is not as easy as that.

You need to build in synchronization between the thread and your main thread a.k.a. main the above code will exit your program without doing anything.

instead you need to have some kind of communication going between thread and main so that you can handle things like program termination, errors in the thread and done signal from the thread etc.

All multi-threading looks at first pretty easy and intuitive but you always get more than you bargain for.
Topic archived. No new replies allowed.