this is how i do it (not using pools), i have modified my code for your
purposes, though it's probably wrong somewhere in the implementation details
(i didn't even compile it), but i leave that to you.
this is very easily generalizable to do any kind of background work on a
"list" of items.
richard
=== BEGIN code snippet ===
{ // in the main routine
gfloat *retPtr, tot_err;
GQueue *threadsQ = g_queue_new(); // Q holding list of data items to
process
data_t data[N_DATAPOINTS]; // data items to process
fill_the_data_array(data);
for(i = 0;
i < N_DATAPOINTS;
i++)
{
g_queue_push_head(threadsQ, &data[i]); // put data item onto Q for
processing
}
g_thread_init(NULL);
commQ = g_async_queue_new(); // create comms Q
threadsProc(threadsQ, maxThreads); // initiate threads
retPtr = (g_float*) g_async_queue_pop(commQ); // sit and wait for all
threads in threadsProc() to complete...
tot_err = *retPtr; // the answer
}
// all the rest in a different source file...
static GQueue *threadsQ; // Q holding the data to process
static int numThreads; // number of threads (and a counter too)
static g_float *tot_err; // array of g_float, one element per thread
static g_float total_errors; // total errors, added up, returned to main
static GStaticMutex QMutex = G_STATIC_MUTEX_INIT; // mutex to read Q
typedef struct _THREADARGS
{ // structure of arguments to thread proc
GThreadFunc returnFunc;
int threadNum;
} THREADARGS;
static void finishThreads()
{ // called once a thread has finished its work
numThreads--;
if (!numThreads)
{ // return to main routine
int i;
g_float retValue = 0;
for (i = 0;i<numThreads; i++)
retValue += tot_err[i];
total_errors = retValue;
g_async_queue_push(commQ, &total_errors);
}
}
static data_t *get_data()
{ // get the next data item off the Q to process, called by _addData()
data_t *data;
g_static_mutex_lock(&QMutex);
data = g_queue_pop_head(threadsQ);
g_static_mutex_unlock(&QMutex);
return (data);
}
static void _addData(THREADARGS *threadArgs)
{ // processing thread
int threadNum = threadArgs->threadNum;
GThreadFunc retFunc = threadArgs->returnFunc;
data_t *data = get_data(); // get a data item to process
while (data)
{
tot_err[threadNum] += calc_error(data);
data = get_data(); // until no more to do
}
(*(retFunc))(NULL);
}
void threadsProc(GQueue *q, int nThreads)
{
int i;
numThreads = nThreads;
tot_err = calloc(numThreads, sizeof(g_float));
threadsQ = q;
for(i=0;i<numThreads;i++)
{
THREADARGS *threadArgs;
threadArgs = calloc(1, sizeof(THREADARGS));
threadArgs->returnFunc = (GThreadFunc) finishThreads;
threadArgs->threadNum = i;
g_thread_create((GThreadFunc) _addData, (void *) threadArgs, FALSE, NULL);
}
}
=== END code snippet ===
2010/7/23 Øystein Schønning-Johansen <[email protected]>
> I tried, and the new problem is now:
>
> pool = g_thread_pool_new( my_calc, (gpointer) &common, 8, FALSE, &err );
>
> for (i = 0; i < n_tot; i++ )
> g_thread_pool_push( pool, &store[i], &err );
>
> g_thread_pool_free( pool, FALSE, TRUE );
>
> When I run this code, it continues without waiting for the threads to
> complete. I expected that the g_thread_pool_free function would make it
> wait
> for all threads to complete before the program code continues, however
> it does not! How can I make it wait?
>
> (Yes, I added a static mutex in my_func. I'm convinced that I need it. )
>
> -Øystein
> _______________________________________________
> gtk-list mailing list
> [email protected]
> http://mail.gnome.org/mailman/listinfo/gtk-list
>
_______________________________________________
gtk-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-list