最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

how to call async function for timer in python - Stack Overflow

programmeradmin10浏览0评论

I would like two parameters: freq1 and freq2 to swap at a interval freq_change_interval - this is in a existing python project which already uses async in some methods, but the existing main(): method is not async.

The parameters are from the command line arguments, and the context of the project is that it reads in data from a software defined radio (SDR).

A cutdown copy of the module containing main(): looks like this:

import asyncio
import argparse
from trackermon import ProcessConfig, ProcessResult, SampleConfig

def main():
    p = argparse.ArgumentParser()
    ...
    s_group = p.add_argument_group("Sampling")
    ...
    s_group.add_argument(
        "--freq1",
        dest="freq1",
        type=float,
        default=SampleConfig.freq1,
        help=" frequency 1 (default: %(default)s)",
    )
    s_group.add_argument(
        "--freq2",
        dest="freq2",
        type=float,
        default=SampleConfig.freq2,
        help=" frequency 2 (default: %(default)s)",
    )
    s_group.add_argument(
        "--interval",
        dest="freq_change_interval",
        type=float,
        default=SampleConfig.freq_change_interval,
        help=" interval (default: %(default)s)",
    )
    
    ...
    
    sample_config = SampleConfig(
        freq1=args.freq1,
        freq2=args.freq2,
        freq_change_interval=args.freq_change_interval,
    )

    elif args.radio == "airspy":
        from tracker.sample_reader_airspy import \
            BufferAirspy as SampleBuffer
        from tracker.sample_reader_airspy import \
            SampleReaderAirspy as SampleReader

        process_config.running_mode = "radio"
        asyncio.run(
            pipeline(
                process_config=process_config,
                source_gen=source_radio(
                    reader=SampleReader(sample_config),
                    buffer=SampleBuffer(),
                    num_samples_to_process=process_config.num_samples_to_process,
                ),
                task_results=results_pipeline,
            )
        )
    
async def other_methods():

async def results_pipeline(....)

if __name__ == "__main__":
    main() 

I have read about async functions and the minimum examples I have seen I can not integrate into the context of the existing code.

Q: How can I have something working that resembles the pseudo code:

if sample_config.freq_change_interval > 0:
    await asyncio.sleep(sample_config.freq_change_interval)
    freq1, freq2 = freq2, freq1 # swap frequencies when interval is reached

I would like two parameters: freq1 and freq2 to swap at a interval freq_change_interval - this is in a existing python project which already uses async in some methods, but the existing main(): method is not async.

The parameters are from the command line arguments, and the context of the project is that it reads in data from a software defined radio (SDR).

A cutdown copy of the module containing main(): looks like this:

import asyncio
import argparse
from trackermon import ProcessConfig, ProcessResult, SampleConfig

def main():
    p = argparse.ArgumentParser()
    ...
    s_group = p.add_argument_group("Sampling")
    ...
    s_group.add_argument(
        "--freq1",
        dest="freq1",
        type=float,
        default=SampleConfig.freq1,
        help=" frequency 1 (default: %(default)s)",
    )
    s_group.add_argument(
        "--freq2",
        dest="freq2",
        type=float,
        default=SampleConfig.freq2,
        help=" frequency 2 (default: %(default)s)",
    )
    s_group.add_argument(
        "--interval",
        dest="freq_change_interval",
        type=float,
        default=SampleConfig.freq_change_interval,
        help=" interval (default: %(default)s)",
    )
    
    ...
    
    sample_config = SampleConfig(
        freq1=args.freq1,
        freq2=args.freq2,
        freq_change_interval=args.freq_change_interval,
    )

    elif args.radio == "airspy":
        from tracker.sample_reader_airspy import \
            BufferAirspy as SampleBuffer
        from tracker.sample_reader_airspy import \
            SampleReaderAirspy as SampleReader

        process_config.running_mode = "radio"
        asyncio.run(
            pipeline(
                process_config=process_config,
                source_gen=source_radio(
                    reader=SampleReader(sample_config),
                    buffer=SampleBuffer(),
                    num_samples_to_process=process_config.num_samples_to_process,
                ),
                task_results=results_pipeline,
            )
        )
    
async def other_methods():

async def results_pipeline(....)

if __name__ == "__main__":
    main() 

I have read about async functions and the minimum examples I have seen I can not integrate into the context of the existing code.

Q: How can I have something working that resembles the pseudo code:

if sample_config.freq_change_interval > 0:
    await asyncio.sleep(sample_config.freq_change_interval)
    freq1, freq2 = freq2, freq1 # swap frequencies when interval is reached
Share Improve this question edited Mar 29 at 6:28 Radika Moonesinghe asked Mar 27 at 0:51 Radika MoonesingheRadika Moonesinghe 613 bronze badges 4
  • Is the code starting with if sample_config.freq_change_interval > 0: in main (or some non-async function called directly or indirectly from main)? If so, there is no asyncio event loop running and you can just call asyncio.run(asyncio.sleep(sample_config.freq_change_interval)). If, however, this code is in a non-async function called from a async function, i.e. there is already a running event loop, then the answer is more complicated. So you need to describe more completely where this code is. – Booboo Commented Mar 27 at 10:39
  • the code starting with if is juts pseudo code to show what I want it to do. It can go anywhere as its own method or inside main (but main isnt async). I actually thought tracking time.time() might be a better test? ie if time.time() - interval > last_update_time - but IDK – Radika Moonesinghe Commented Mar 28 at 19:46
  • You show a main function that parses its arguments and creates some sort of configuration. You also show some async functions. But what you do not show is how an event loop gets started and some initial async function invoked. These are important, missing details. Assuming that main calls asyncio.run specifying some async coroutine that is passed the configuration and assuming further that you want to periodically swap frequencies, then that initial coroutine could call asyncio.create_task specifying a coroutine that has a loop in which sleeping is followed by swapping frequencies. – Booboo Commented Mar 28 at 20:51
  • The program can be launched in a few different modes (read a file from disk vs read in a stream of data from a radio) - the radio one is the one that needs to swap freq when provided - I think the extra data I have added to the code is the important detail needed? – Radika Moonesinghe Commented Mar 29 at 6:29
Add a comment  | 

1 Answer 1

Reset to default 0

You are creating a configuration named sample_config and passing to pipeline the undefined process_config. Assuming process_config is the same thing as sameple_config and that you periodically want to be swapping frequencies (not just swapping frequencies once), then your pipeline function might look something like:

async def pipeline(process_config,
                   source_gen,
                   task_results):

    # Create the frequency swapper task if required:
    if process_config.freq_change_interval > 0:
        frequency_swapper_task = asyncio.create_task(frequency_swapper(process_config))
    else:
        frequency_swapper_task = None

    ...  # Do whatever you do
    
    # When all done we cancel the frequency swapper task:
    if frequency_swapper_task:
        frequency_swapper_task.cancel()
        try:
            await frequency_swapper_task
        except asyncio.CancelledError:
            pass

And then your frequency swapper task might be:

async def frequency_swapper(process_config):
    # Run until we are canceled:
    while True:
        await asyncio.sleep(process_config.freq_change_interval)
        process_config.freq1, process_config.freq2 = (
            # swap frequencies when interval is reached:
            process_config.freq2, process_config.freq1
        )
发布评论

评论列表(0)

  1. 暂无评论