2017-08-04 41 views
0

我正在嘗試使用C代碼從操縱桿讀取數據。我有found online the way to do it使用read()C函數而不停止代碼

此解決方案似乎工作正常,但有問題。當代碼妻兒的讀()函數,它將停止並等待,直到有變化操縱桿裝置:

int read_event(int fd, struct js_event *event) 
{ 
    ssize_t bytes; 

    bytes = read(fd, event, sizeof(*event)); 
    if (bytes == sizeof(*event)) 
     return 0; 
    return -1; 
} 

我試圖找到一種方法,使代碼運行汽車無,如果沒有在控制設備中改變,只需返回以前的狀態。到目前爲止,我沒有成功。也許有人可以幫忙。

+2

你是如何打開文件描述符的? –

+2

2個選項 - [select(2)](http://man7.org/linux/man-pages/man2/select.2.html)或線程。 –

+0

@EugeneSh。我打開它: device =「/ dev/input/js0」; js = open(device,O_RDONLY);原始鏈接中的 。 –

回答

2

既然你是通過open()打開操縱桿裝置,並通過read()從中讀取,我推斷你是編碼爲實現POSIX接口的機器。對於大多數文件,POSIX read()函數會阻塞,直到它可以傳輸至少一個字節,並且這確實是您觀察到的行爲。

避免這種情況的一種方法是在非阻塞模式下打開文件,或者在打開文件之後但在讀取文件之前將其置於非阻塞模式。您可以通過添加O_NONBLOCK標誌打開的選項做前:

js = open(device, O_RDONLY | O_NONBLOCK); 

這應該與您現有的代碼乾淨,有利地相互作用讀取遊戲杆事件。如果沒有事件可讀取,您的read()呼叫應立即返回,返回值爲-1,errno設爲EAGAIN。否則,它將返回傳輸的字節數。

請注意,一般而言,read()不能保證傳輸您請求的全部字節數 - 它可能會成功讀取更少的數據,您可以從其返回值中確定數量,如果您不考慮此數據,那麼您可以來悲傷。但是,我不認爲你會看到來自操縱桿設備的任何短的讀數。你應該得到一個完整的事件或沒有。

0

我不確定實際的API(系統調用)函數,但我的想法應該工作。

使用類似GetNumberOfInputEvents(WinAPI函數)的東西來確定您的讀取是否會卡住(無需讀取)。然後,如果您判斷它會卡住,請跳過它。

請參閱Checking the stdin buffer if it's empty瞭解更多信息。

僞代碼:

read_event(Event* event){ 
    if (is_event_buffer_empty()) 
     // Do nothing because `read` is stuck 
    else 
     SystemAPI_ReadEvent(event); 
} 
+1

這是非常錯誤的。因爲數據可能在'is_event_buffer_empy()'之後變得不可用 - - 其他線程正在讀取它。 –

+3

OP是通過文件描述符讀取的,而不是流,所以沒有流緩衝區(除非他自己實現一個)。即使存在,緩衝區爲空也不同於沒有可讀取的數據。 –