When I launch a python code from C code, there are many threads that do not stop at the end of the execution of the Python code:
ps -T 20402
PID SPID TTY STAT TIME COMMAND
20402 20402 pts/0 Rl 0:11 ./test
20402 20427 pts/0 Sl 0:00 ./test
20402 20428 pts/0 Sl 0:00 ./test
20402 20443 pts/0 Sl 0:00 ./test
20402 20458 pts/0 Sl 0:00 ./test
20402 20461 pts/0 Sl 0:00 ./test
20402 20464 pts/0 Sl 0:00 ./test
20402 20471 pts/0 Sl 0:00 ./test
These threads seem to be related to the use of libraries related to gnuradio. Here is my code in Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: Weather satellite
# Author: Norian
# GNU Radio version: 3.8.1.0
from gnuradio import analog
from gnuradio import blocks
from gnuradio import filter
from gnuradio.filter import firdes
from gnuradio import gr
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
import osmosdr
import time
class Weather_sat(gr.top_block):
def __init__(self):
gr.top_block.__init__(self, "Weather satellite")
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 1411200
##################################################
# Blocks
##################################################
self.rational_resampler_xxx_0 = filter.rational_resampler_fff(
interpolation=208,
decimation=441,
taps=None,
fractional_bw=None)
self.osmosdr_source_0 = osmosdr.source(
args="numchan=" + str(1) + " " + ""
)
self.osmosdr_source_0.set_time_now(osmosdr.time_spec_t(time.time()), osmosdr.ALL_MBOARDS)
self.osmosdr_source_0.set_sample_rate(samp_rate)
self.osmosdr_source_0.set_center_freq(137100000, 0)
self.osmosdr_source_0.set_freq_corr(0, 0)
self.osmosdr_source_0.set_gain(40, 0)
self.osmosdr_source_0.set_if_gain(20, 0)
self.osmosdr_source_0.set_bb_gain(20, 0)
self.osmosdr_source_0.set_antenna('', 0)
self.osmosdr_source_0.set_bandwidth(0, 0)
self.low_pass_filter_0 = filter.fir_filter_ccf(
16,
firdes.low_pass(
1,
samp_rate,
110000,
10000,
firdes.WIN_HAMMING,
6.76))
self.blocks_wavfile_sink_0 = blocks.wavfile_sink('/home/norian/Documents/GNURADIO/noaadeu.wav', 1, 20800, 16)
self.analog_wfm_rcv_0 = analog.wfm_rcv(
quad_rate=88200,
audio_decimation=2,
)
##################################################
# Connections
##################################################
self.connect((self.analog_wfm_rcv_0, 0), (self.rational_resampler_xxx_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.analog_wfm_rcv_0, 0))
self.connect((self.osmosdr_source_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.rational_resampler_xxx_0, 0), (self.blocks_wavfile_sink_0, 0))
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 110000, 10000, firdes.WIN_HAMMING, 6.76))
self.osmosdr_source_0.set_sample_rate(self.samp_rate)
def main(freq):
top_block_cls=Weather_sat
tb = top_block_cls()
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
tb.start()
try:
input('Press Enter to quit: ')
except EOFError:
pass
tb.stop()
tb.wait()
And here is my C code:
//prgm.c
#include <stdio.h>
#include "Python.h"
int main(void) {
Py_Initialize();
/* add . to the path */
PyObject* sys = PyImport_ImportModule("sys");
PyObject* path = PyObject_GetAttrString(sys, "path");
PyList_Insert(path, 0, PyUnicode_FromString("."));
/* import desired function */
PyObject* pModule = PyImport_ImportModule("main");
PyObject* pFunc = PyObject_GetAttrString(pModule, "main");
/* call it */
PyObject* pArgs = Py_BuildValue("(s)", "137912500");
PyObject_CallObject(pFunc, pArgs);
Py_Finalize();
fprintf(stderr,"End of python software");
while(1);
return 0;
}
Can you explain to me how to detect threads created by python and kill them?
I am working on Ubuntu 20.4. I am using gnuradio version 3.8 and I installed it from apt.
Thank you very much for your help.
Perhaps gnuradio creates threads from its own C API? – user23952
Exactly. GNU Radio is a heavily multithreaded application.
Can you explain to me how to detect threads created by python and kill them?
You can "kill" processes, you can't "kill" threads - you can interrupt/join them (which is akin in the sense that it means they don't get scheduled anymore, but different in the sense that the resources allocated to them don't disappear – because threads don't hold own resources (aside from a stack), it's the process that does.
Note that existing threads in themselves are not inherently a problem - it's perfectly normal for a program to have dormant threads that get cleaned up on exit by the operating system and not earlier; threads serve various purposes, including things like handling signals, waiting for RPC connections, managing other resources... which might not even occur in your case.
Do you know how to exit the gr-osmosdr block properly?
This might very well be a problem of the specific driver source encapsulated in the osmosdr source.
Probably this all exits "properly", you've not actually described anything that goes wrong!