【发布时间】:2019-07-04 11:05:37
【问题描述】:
我继承了一些在 Linux 嵌入式平台上运行的 ALSA 代码。
现有实现使用snd_pcm_readi() 和snd_pcm_writei() 进行阻塞 读写。
我的任务是让它在 ARM 处理器上运行,但我发现阻塞的交错读取将 CPU 推到了 99%,所以我正在探索非阻塞读取和写入。
我按预期打开设备:
snd_pcm_handle *handle;
const char* hwname = "plughw:0"; // example name
snd_pcm_open(&handle, hwname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
然后会发生其他 ALSA 内容,我可以根据要求提供。
在这一点上值得注意的是:
- 我们将采样率设置为 48,000 [Hz]
- 样本类型是带符号的 32 位整数
- 设备总是将我们请求的周期大小覆盖为 1024 帧
像这样读取流:
int32* buffer; // buffer set up to hold #period_size samples
int actual = snd_pcm_readi(handle, buffer, period_size);
在阻塞模式下完成此调用大约需要 15 [ms]。显然,变量actual 返回时会读取 1024。
问题是;在非阻塞模式下,这个函数也需要 15 毫秒才能完成,actual 在返回时也总是读取 1024。
我希望函数会立即返回,actual 是
在两次读取尝试之间,我计划让线程休眠一段特定的时间,从而将 CPU 时间留给其他进程。
我是否误解了 ALSA API?还是我的代码缺少关键步骤?
【问题讨论】:
-
在阻塞模式下,
snd_pcm_read*()休眠并等待来自设备的中断。您的 CPU 使用问题不是阻塞模式引起的。 -
来自
snd_pcm_readi()上的 ALSA 文档:“如果选择了非阻塞行为,则例程根本不会等待。”