2013-07-31 116 views
3

我有一個問題,我試圖解決有關Linux中的串行端口。我可以打開,閱讀和關閉端口。但是,我想確保在任何時候我都是唯一一個從港口讀寫的人。鎖定Linux串行端口

我認爲這已經爲我做了open()函數調用後。但是,我可以在我的程序的同一端口上多次調用open()。我也可以有兩個線程同時從同一個端口讀取。

我試着用flock()修復這個問題,我仍然有同樣的問題。是否因爲兩個系統調用都來自同一個pid,即使每組打開和讀取都涉及不同的文件描述符?爲了記錄,兩個open()調用都返回一個有效的文件描述符。

因此,我想知道是否有任何方法可以通過解決問題。從我的程序角度來看,如果兩次調用open()在同一個端口上成功,這並不是什麼大事,因爲程序員應該知道它們引起的鬧劇。但是,我只想確保當我打開一個端口時,我是唯一訪問它的進程。

感謝您的幫助。

+0

我已經問過關於[在Linux中鎖定串行端口和其他設備的「最佳實踐」方法]的問題(http://stackoverflow.com/questions/30316722/what-is-the-best-practice-用於鎖定串行端口和 - 其他的設備,在Linux的)。 –

回答

10

在Linux中,你可以使用TIOCEXCL TTY ioctl來從後面停止其他open() s到設備(他們會與errno==EBUSY,設備或資源忙返回-1)。這隻適用於終端和串行設備,但它不依賴於諮詢鎖定。

例如:

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <termios.h> 
#include <fcntl.h> 
#include <errno.h> 

int open_device(const char *const device) 
{ 
    int descriptor, result; 

    if (!device || !*device) { 
     errno = EINVAL; 
     return -1; 
    } 

    do { 
     descriptor = open(device, O_RDWR | O_NOCTTY); 
    } while (descriptor == -1 && errno == EINTR); 
    if (descriptor == -1) 
     return -1; 

    if (ioctl(descriptor, TIOCEXCL)) { 
     const int saved_errno = errno; 
     do { 
      result = close(descriptor); 
     } while (result == -1 && errno == EINTR); 
     errno = saved_errno; 
     return -1; 
    } 

    return descriptor; 
} 

希望這有助於。

0

我能夠解決使用flock()函數的問題。出於某種原因,使用結構和fcntl()不適合我。通過使用flock(),我可以添加兩行代碼並解決我的問題。

+1

這個答案令人困惑,因爲在你的問題中,你說過你試過使用'flock()',但它不起作用。現在你在說'flock()'是解決方案。什麼? –

+0

在原來的問題中,你可能會說'fcntl()'不起作用,而不是'flock()'? –