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

Reply via email to