Создание дубликата файла нового потока дескрипторы и снабжают дескрипторы сокетом в Linux?

Этот oughta делает это.

DateTimePicker1.Value = DateTime.Now.AddDays(-1).Date;
11
задан Robert S. Barnes 5 October 2009 в 19:47
поделиться

3 ответа

Нет. Потоки используют одну и ту же память, поэтому они используют одни и те же переменные. Если вы закроете сокет в родительском потоке, он будет также закрыт в дочернем потоке.

РЕДАКТИРОВАТЬ:

  • man fork: Потомок наследует копии родительского набора открытых файловых дескрипторов.

  • man pthreads: потоки совместно используют ряд других атрибутов (т. е. эти атрибуты относятся к процессу, а не к потоку): [...] дескрипторы открытых файлов

И некоторый код:

#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);
}

Вывод:

thread: begin
main: file is closed
thread: close() failed: Bad file descriptor
thread: end
10
ответ дан 3 December 2019 в 03:18
поделиться

В Linux потоки реализуются через системный вызов clone с использованием флага CLONE_FILES:

Если установлен CLONE_FILES, вызывающий процесс и дочерние процессы разделяют та же таблица файловых дескрипторов. любой дескриптор файла, созданный вызывающим процесс или дочерний процесс также действует в другом процессе. Аналогично, если один из процессов закрывает файловый дескриптор или изменяет связанные с ним флаги (используя fcntl (2) F_SETFD operation), другой процесс также затронут.

Также посмотрите исходный код glibc, чтобы узнать, как он используется в 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);
9
ответ дан 3 December 2019 в 03:18
поделиться

В принципе, Linux clone () может реализовать не только новый процесс (например, fork ()) или новый поток (например, pthread_create, возможно), но и все, что находится между ними.

На практике он всегда используется только для одного или другого. Потоки, созданные с помощью pthread_create, совместно используют файловые дескрипторы со всеми другими потоками в процессе (а не только с родительским). Это не подлежит обсуждению.

Совместное использование файлового дескриптора и получение копии - это другое дело. Если у вас есть копия (например, fork ()), все копии должны быть закрыты до того, как дескриптор файла исчезнет. Если вы поделитесь FD в потоке, после его закрытия он исчезнет.

9
ответ дан 3 December 2019 в 03:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: