2009-10-05 33 views
10

Mọi người đều biết mô hình cổ điển của một quá trình lắng nghe các kết nối trên một ổ cắm và giả mạo một quy trình mới để xử lý từng kết nối mới. Thực hành bình thường là cho quá trình cha mẹ để ngay lập tức gọi close trên ổ cắm mới được tạo ra, giảm số lượng xử lý để chỉ có đứa trẻ có một tay cầm vào ổ cắm mới.Tạo một chủ đề mới Mô tả tập tin trùng lặp và bộ mô tả socket trong Linux?

Tôi đã đọc rằng chỉ khác biệt duy nhất giữa quy trình và chuỗi trong Linux là các chuỗi chia sẻ cùng một bộ nhớ. Trong trường hợp này, tôi giả sử sinh ra một luồng mới để xử lý một kết nối mới cũng sao chép các mô tả tập tin và cũng sẽ yêu cầu chuỗi 'cha' để đóng bản sao của socket đó?

+0

"* Tôi đã đọc rằng sự khác biệt duy nhất giữa một tiến trình và một chuỗi trong Linux là các chủ đề chia sẻ cùng một bộ nhớ. *" Có rất nhiều sự khác biệt khác giữa các quy trình và luồng. Ví dụ, các tiến trình có thể chứa nhiều hơn một luồng. –

Trả lời

8

Không. Chủ đề chia sẻ cùng một bộ nhớ, vì vậy chúng chia sẻ cùng một biến. Nếu bạn đóng socket trong thread cha, nó cũng sẽ được đóng trong thread con.

EDIT:

  • người đàn ông ngã ba: Đứa trẻ được thừa hưởng bản của bộ của cha mẹ các file descriptor mở.

  • người pthreads: đề phần một loạt các thuộc tính khác (ví dụ, những thuộc tính này là quá trình toàn hơn là mỗi chủ đề): [...] mở file descriptor

Và một số mã:

#include <cstring> 
#include <iostream> 
using namespace std; 

#include <errno.h> 
#include <fcntl.h> 
#include <pthread.h> 
#include <unistd.h> 

// global variable 
int fd = -1; 

void * threadProc(void * param) { 
    cout << "thread: begin" << endl; 
    sleep(2); 
    int rc = close(fd); 
    if (rc == -1) { 
     int errsv = errno; 
     cout << "thread: close() failed: " << strerror(errsv) << endl; 
    } 
    else { 
     cout << "thread: file is closed" << endl; 
    } 
    cout << "thread: end" << endl; 
} 

int main() { 
    int rc = open("/etc/passwd", O_RDONLY); 
    fd = rc; 

    pthread_t threadId; 
    rc = pthread_create(&threadId, NULL, &threadProc, NULL); 

    sleep(1); 

    rc = close(fd); 
    if (rc == -1) { 
     int errsv = errno; 
     cout << "main: close() failed: " << strerror(errsv) << endl; 
     return 0; 
    } 
    else { 
     cout << "main: file is closed" << endl; 
    } 

    sleep(2); 
} 

Output là:

thread: begin 
main: file is closed 
thread: close() failed: Bad file descriptor 
thread: end 
+0

Bạn có tham khảo không? –

+0

Tôi không có nó ở đây tại nơi làm việc, nhưng tôi có thể kiểm tra bản sao của tôi về Stevens 'UNPv2 khi tôi về nhà. –

+0

@Shelby - Cảm ơn, tôi có một bản sao UNP nhưng chỉ đọc được khoảng một phần ba của nó. –

9

On đề Linux được thực hiện thông qua các clone syscall sử dụng lá cờ CLONE_FILES:

Nếu CLONE_FILES được thiết lập, gọi quá trình và các quá trình con chia sẻ cùng một bảng mô tả tập tin. Bất kỳ bộ mô tả tệp nào được tạo bằng quy trình gọi số hoặc theo quy trình con là cũng hợp lệ trong quy trình khác. Tương tự, nếu một trong các quy trình đóng bộ mô tả tệp hoặc thay đổi cờ được liên kết của nó (sử dụng thao tác fcntl (2) F_SETFD), quá trình khác cũng bị ảnh hưởng.

Cũng có một cái nhìn vào mã nguồn glibc cho các chi tiết của nó như thế nào được sử dụng trong createthread.c:

int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL 
      | CLONE_SETTLS | CLONE_PARENT_SETTID 
      | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM 
#if __ASSUME_NO_CLONE_DETACHED == 0 
      | CLONE_DETACHED 
#endif 
      | 0); 
8

Về nguyên tắc, Linux clone() có thể thực hiện không chỉ là một tiến trình mới (như ngã ba()), hoặc một chủ đề mới (như pthread_create có lẽ), nhưng cũng bất cứ điều gì ở giữa.

Trong thực tế, nó chỉ được sử dụng cho cái này hay cái kia. Các chủ đề được tạo với pthread_create chia sẻ các bộ mô tả tập tin với tất cả các luồng khác trong tiến trình (không chỉ phụ huynh). Điều này là không thể thương lượng.

Chia sẻ bộ mô tả tệp và có bản sao khác.Nếu bạn có một bản sao (như fork()) thì tất cả các bản sao phải được đóng trước khi xử lý tập tin biến mất. Nếu bạn chia sẻ FD trong một chủ đề, một khi một đóng nó, nó đã biến mất.

Các vấn đề liên quan