[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] GnuRadio flowgraphs in workerthread

From: Johnathan Corgan
Subject: Re: [Discuss-gnuradio] GnuRadio flowgraphs in workerthread
Date: Fri, 11 Oct 2013 10:30:46 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.0

On 10/11/2013 07:52 AM, Alex3371 wrote:

> would it affect the performance of my GNURadio-programm negatively if
> I tried to run my GNURadio flowgraphs in a workerthread instead of
> the mainthread. In the mainthread I would like to implement a custom
> wxPython GUI.

It is entirely possible to instantiate a GNU Radio flowgraph in a
separate thread from the main one, though it's not clear in your use
case if it is needed. There is no performance impact. The runtime will
create individual threads for each block anyway.

> Also, I still do not understand what the happens when I call wait() 
> and/or stop(). I have two flowgraphs, one for receiving and one for 
> transmitting with the USRP2. Both use a gr.head block and run to 
> completion after they have proccessed a certain ammount of samples.

The run() function on a top block is a wrapper around calls to start()
and wait().  The flowgraph will operate either until it exits on it's
own or until it is terminated by a signal (like ctrl-c).  The calling
thread context is blocked waiting for the internal wait() call to
return.  This is the typical way to run flowgraphs that don't need to do
anything else in the calling thread context.

You can retain control of the calling thread context by instead doing
this manually.

Calling start() on a top block creates a running thread per block (among
many other things), then returns to the calling context. You are free
then to do anything else needed in your application, and the GNU Radio
flowgraph runs "in the background."  This is how you would run control
code in Python that talks to the flowgraph through some mechanism like
messaging or function calls on individual blocks.

To end the flowgraph at some point, you call stop(), which sends an
interrupt to each of the GNU Radio block threads.  Finally, you call
wait(), which internally joins all the interrupted threads, so that when
wait() returns, all the flowgraph threads are known to have completed.

> I did some testing and it seems to work fine. But still I would like
>  to know if the following lines of Code make any sense:

In your case, since you are using head blocks, the flowgraph will exit
on its own when the requested number of samples have passed through the
head block.  However, you are trying to coordinate the activity of two
separate top blocks.  If you called run() on the first one, it would not
return from that call until the flowgraph exited, and your second
flowgraph would get started too late.

The first way to solve this is to call start() on each top block, then
call wait() each of them sequentially.  Thus, the two flowgraphs operate
simultaneously, and each one "exits" when its head block is done.  The
calls to wait() will ensure that your application while loop does not
continue until this happens.

The second (and better) way to do this is to put both signal processing
chains into one flowgraph.  Convert each of them to a hierarchical block
with no inputs or outputs, then create a top block, and use the
tb.connect() method:

tb = gr.top_block()
receiver = receiver_class() # now a hierarchical block with no I/O
transmitter = transmitter_class() # also a hierarchical block


while (1):
        tb.start() # starts threads
        # Do stuff while the flowgraph is running (if needed)
        tb.wait() # blocks until both hier blocks are in done state
        # Do stuff in between flowgraph runs (if needed)

In your particular case, since you are using head blocks in both chains,
you could use run() in the loop instead of start() and wait(). The
flowgraph would finish naturally and run() would return.  This would not
let you, however, do anything while the flowgraph was running.

Finally, if you ever change the flowgraph such that it "runs forever"
instead of exiting on its own, you'd need to have a call to tb.stop() in
there at the point your control logic needs to shut things down.

Hope this makes things clearer.

Johnathan Corgan, Corgan Labs
SDR Training and Development Services

Attachment: johnathan.vcf
Description: Vcard

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]