我在使用python的過程當中發現了這個有這樣的錯誤,后來看了下面這篇文檔才知道原因所在。
最近在編寫一個局域網的聊天工具,在編寫客戶端時,我把界面部分和事件處理函數寫好后,准備再開一個線程用於接收服務器端發來的數據報,根據數據報的類型來調用相應的子模塊。我用的是gtk+寫的界面,由於兩個線程都涉及到界面的問題,並且我並沒有考慮同步的問題,所以導致了標題中所說的問題。
我的數據接收模塊(單獨的一個線程)的大致內容如下:
while ( RecvInfo(datagram, &size_datagram) ){
/* 提取報文頭 */
struct ConnProto *ptr = (struct ConnProto *)pData;
pconn = *ptr;
if (pconn.type == 0) {
// 當前登錄成功,下載用戶列表
}else if (pconn.type == -1) {
// 當前用戶已登錄,先下線
gchar str[100] = "系統提示:[當前用戶已登錄,請先下線]";
message_box(str, GTK_MESSAGE_ERROR);
}else if (pconn.type == -2) {
// 當前用戶不存在,先注冊
}else if (pconn.type == -3) {
// 當前用戶密碼錯誤
}else if (pconn.type == 10) {
// 有新用戶上線
}else if (pconn.type == 11) {
// 注冊成功
}else if (pconn.type == -11) {
// 當前用戶已存在
}else if (pconn.type ==2) {
// 私聊處理
}else if (pconn.type == 3) {
// 群聊處理
}else if (pconn.type == 4) {
// 退出處理
}else {
// 其他處理
gchar str[100] = "系統提示:[當前有不識別的命令]";
message_box(str, GTK_MESSAGE_ERROR);
}
}
其中,message_box ()函數涉及到界面的問題,就是一個消息框的界面。剛開始的時候,while循環中沒有放置sleep()函數(你可能會有疑問為什么放置這個函數,其實我的接收數據的函數RecvInfo () 函數還沒有寫,我只是用一個空函數代替,所以如果不放置sleep ()的話,循環速度就會太快),出現的問題如下:
chat: Fatal IO error 11 (資源暫時不可用) on X server :0.0.
當在 while ()循環中加入 sleep (2)時,出現的問題如下:
The program 'chat' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadIDChoice (invalid resource ID chosen for this connection)'.
(Details: serial 761 error_code 14 request_code 144 minor_code 2)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the --sync command line
option to change this behavior. You can then get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)
在網上搜了一下,說是由於兩個線程搶占GUI資源導致的,去除其中一個線程中的控件句柄,說白了就是只能有一個線程來畫界面。
實際上,在gtk+程序中使用線程的話,不能直接使用 linux 中的 pthread 了,而應該用 gtk+ 中提供的線程函數。關於 gtk+ 中使用多線程的方法,詳見另一篇文章。