【发布时间】:2011-08-04 18:42:45
【问题描述】:
我一直在尝试使用 GNU Radio,并遇到了 tunnel.py 程序。该程序允许您使用 Linux TUN/TAP 设备通过无线电链路传输 IP 流量。大多数情况下它都在工作,但是其中一部分代码让我感到困惑。
有一个类实现了“基本 MAC 层”。这个类有一个回调函数,它将一个新的数据包写入 TUN 设备。此函数 (phy_rx_callback) 是从单独的线程调用的。
main_loop 函数在传输新数据包之前进行载波侦听。我不明白的是为什么它会在单独的非重叠传输通道上传输之前检测接收通道。
RX 和 TX 通道都是独立的频率,我们的硬件允许全双工通信。
所以,我的问题是main_loop 执行,另一个线程异步调用phy_rx_callback 函数的含义是什么?问题是我试图了解载波侦听循环的目的,我发现注释该代码会严重降低性能。对我来说,在使用传输通道之前监视接收通道是没有意义的,基本上将其变成半双工。然后我看不出使用两个频率的目的,一个用于发送,一个用于接收。我开始怀疑这里是否存在奇怪的线程问题。
最初创建cs_mac 类的单个实例。指向 rx_callback 函数的“指针”会向下传递几个级别到实际调用它的线程类。这是 cs_mac 类:
class cs_mac(object):
def __init__(self, tun_fd, verbose=False):
self.tun_fd = tun_fd # file descriptor for TUN/TAP interface
self.verbose = verbose
self.tb = None # top block (access to PHY)
def set_top_block(self, tb):
self.tb = tb
def phy_rx_callback(self, ok, payload):
if self.verbose:
print "Rx: ok = %r len(payload) = %4d" % (ok, len(payload))
if ok:
os.write(self.tun_fd, payload)
def main_loop(self):
min_delay = 0.001 # seconds
while 1:
payload = os.read(self.tun_fd, 10*1024)
if not payload:
self.tb.send_pkt(eof=True)
break
if self.verbose:
print "Tx: len(payload) = %4d" % (len(payload),)
delay = min_delay
while self.tb.carrier_sensed():
sys.stderr.write('B')
time.sleep(delay)
if delay < 0.050:
delay = delay * 2 # exponential back-off
self.tb.send_pkt(payload)
好的,所以使用ctypes.CDLL('libc.so.6').syscall(186)),它调用gettid,我发现调用rx_callback函数的线程具有相同的PID,但不同的TID。
问题变成了,让一个单独的线程从主线程中的一个对象调用一个函数(而该线程不断循环)意味着什么?
【问题讨论】:
-
不能说我对 GNU Radio 了解很多,但这是我的 2 美分。将 TX 和 RX 放在不同的线程中应该不会有问题,只要它们在 GNU Radio 端使用不同的资源——无论是软件还是硬件。你说他们使用不同的频道,所以听起来他们可能是分开的。另一方面,它们使用的是同一个天线,那么你真的可以同时发射和接收吗?
标签: python multithreading gnuradio