2010-03-21 44 views
7

Tôi có một vòng lặp mà về cơ bản gọi này mỗi vài giây (sau thời gian chờ):phá vỡ ra khỏi ổ cắm chọn

while(true){ 

    if(finished) 
     return; 

    switch(select(FD_SETSIZE, &readfds, 0, 0, &tv)){ 
     case SOCKET_ERROR : report bad stuff etc; return; 
     default : break; 
    } 

    // do stuff with the incoming connection 
} 

Vì vậy, về cơ bản cho mỗi vài giây (được xác định bởi tv), nó reactivates lắng nghe .

Điều này được chạy trên chuỗi B (không phải là chủ đề chính). Có những lúc tôi muốn kết thúc vòng lặp chấp nhận này ngay lập tức từ luồng A (chủ đề chính), nhưng có vẻ như tôi phải đợi cho đến khi khoảng thời gian kết thúc ..

Có cách nào để làm gián đoạn chức năng chọn từ chuỗi khác để luồng B có thể thoát ngay lập tức?

+0

Sidenote: bạn có thể cắt if-statement và chỉ viết trong khi (! Finished). –

+0

Điều đó sẽ mất 100% thời gian CPU. Chắc chắn không được chấp nhận. – kamziro

+0

Rất tiếc, tôi phải hiểu sai rằng – kamziro

Trả lời

9

Cách dễ nhất có thể là sử dụng pipe(2) để tạo đường ống và thêm đầu đọc vào readfds. Khi thread khác muốn ngắt select() chỉ cần viết một byte vào nó, sau đó tiêu thụ nó sau đó.

+0

Đó là một ổ cắm nghe (một trong đó chấp nhận các kết nối). Điều này vẫn sẽ làm việc? Tôi đã nghĩ đến việc gọi một số chức năng phá hủy ổ cắm .. để xem điều gì xảy ra. Điều này có an toàn không? – kamziro

+1

Nó đang chờ tệp * a *. Nó không quan tâm * mà *, nó chỉ muốn * một cái gì đó *. –

+0

Nó hoạt động, và tôi đã học được một hoặc hai điều với các ống unix! Cảm ơn! Nhân tiện, tất cả những gì tôi đang làm sau khi ngắt là thoát khỏi chương trình. vì vậy tôi không làm phiền với việc tiêu thụ. Không sao chứ? – kamziro

3

Có, bạn tạo một cặp ổ cắm được kết nối. Sau đó, luồng B ghi vào một bên của socket và luồng A sẽ thêm ổ cắm bên kia để chọn. Vì vậy, một khi B ghi vào ổ cắm Một lối ra chọn, đừng quên đọc byte này từ ổ cắm.

Đây là cách tiêu chuẩn và phổ biến nhất để làm gián đoạn các lựa chọn.

Ghi chú:

Dưới Unix, sử dụng socketpair để tạo ra một cặp ổ cắm, dưới cửa sổ đó là một chút khó khăn nhưng googling cho Windows socketpair sẽ cung cấp cho bạn các mẫu mã.

+0

Ah, tôi vừa sử dụng đường ống (2) và nó có vẻ hoạt động . Tôi có thể phải lo lắng về đối tác cửa sổ của nó cuối cùng .. – kamziro

-1

Bạn có thể không làm cho thời gian chờ đủ ngắn (như 10ms hay không?).

Những giải pháp "vừa tạo kết nối giả" này có vẻ như bị tấn công. Cá nhân tôi nghĩ rằng nếu một ứng dụng được thiết kế tốt, các tác vụ đồng thời không bao giờ bị gián đoạn một cách mạnh mẽ, chỉ cần kiểm tra nhân viên đủ thường xuyên (đây cũng là lý do tại sao boost.threads không có chức năng chấm dứt).

Chỉnh sửa Làm câu trả lời này CV. Nó là xấu, nhưng nó có thể giúp người khác hiểu tại sao nó là xấu, được giải thích trong các ý kiến.

+1

-1 Đây là giải pháp rất xấu mà chỉ cần chi phí CPU và vẫn có vấn đề chậm trễ. Có những giải pháp tiêu chuẩn cho việc này. – Artyom

+0

CPU chi phí như thế nào? 10ms chờ CPU so với việc tạo kết nối ổ cắm giả là gì? –

+1

Chi phí CPU là giảm thời gian chờ, làm cho vòng lặp chạy thường xuyên hơn. – caf

-1

Bạn có thể sử dụng cuộc gọi tắt (Sock, SHUT_RDWR) từ chủ đề chính để thoát khỏi cuộc gọi chọn chờ cũng sẽ thoát khỏi chuỗi khác trước khi hết thời gian chờ, do đó bạn không cần đợi đến khi hết thời gian chờ.

cổ vũ. :)

+1

Thật không may, bạn không thể 'tắt máy nghe'. Và không có cách nào an toàn để 'đóng' nó trong khi một luồng khác, hoặc có thể là, sử dụng nó. –

+0

Nếu bạn có một chức năng thread socket được đề cập dưới đây và nếu bạn gửi shutdown (sock, SHUT_RD) từ chủ đề chính nó sẽ đánh thức chờ cuộc gọi chọn từ thực thi SockThreadFunction trong thread khác. Tôi đã thử điều này và làm việc tốt. SockThreadFunction() {while (SocketOpen) {// Đang đợi Chọn cuộc gọi int Sẵn sàng = chọn (pSocket-> m_Sock + 1, & SockSet, 0, 0, 0); } –

+0

Anh ấy có một ổ cắm nghe. Bạn không thể 'tắt' một ổ cắm nghe. Nó sẽ làm việc cho các ổ cắm được kết nối, nhưng nó sẽ không hoạt động đối với một ổ cắm nghe, đó là những gì anh ta có. –