Нет. Как только файловый дескриптор закрывается, он больше не доступен ни для чего, кроме как для использования ядром в новом файловом дескрипторе. Как только вы не получите его снова в результате нового системного вызова open(2)
, create(2)
, socket(2)
и т. д., его нельзя будет использовать в качестве параметра для любого системного вызова (включая select(2)
и epoll(2)
)
Ядро освободило запись файлового дескриптора в структуре вашего процесса, поэтому ее нельзя использовать.
Извините, я сказал:
Единственный способ получить что-то от epoll(2)
в случае его закрытия - это если у вас есть два потока и вы close(2)
дескриптор файла в одном потоке, пока вы ожидаете его в другом потоке. На этот раз вы получите немедленный возврат из системного вызова epoll(2)
, возможно, с какой-то ошибкой (я не проверял это), но я думаю, что это не ваш сценарий.
Как я тогда сказал, я его не проверял, но сейчас могу сказать, что системные вызовы в процессе не прерываются, а оставляются до конца. В любом случае, файловый дескриптор больше недействителен ни в одном потоке, который будет использоваться для нового системного вызова. Код в ПРИМЕЧАНИИ ниже показывает, как это происходит. Но вывод таков, что после close(2)
вы больше не сможете использовать в процессе дескриптор файла, переданный системному вызову, как я уже говорил. (конечно, вы можете, если вы получите то же значение файлового дескриптора в результате нового системного вызова open(2)
, socket(2)
и т. д.)
ПРИМЕЧАНИЕ
только что протестировано со следующим кодом: если вы close(2)
дескриптор файла и другие потоки заблокированы в системных вызовах, связанных с этим дескриптором файла, системные вызовы не прерываются, но дескриптор файла больше недействителен. После завершения этих системных вызовов файловый дескриптор становится непригодным для использования ни в потоке, который его close(2)
d, ни в других потоках.
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
char buffer[100];
void *f(void* arg)
{
int res;
printf("f: waiting on read()\n");
res = read(0, buffer, sizeof buffer);
printf("f: read %d bytes\n", res);
if (res < 0) {
printf("this was an error: %s\n", strerror(errno));
} else {
printf("f: read: %.*s", res, buffer);
}
printf("f: waiting on read()\n");
res = read(0, buffer, sizeof buffer);
printf("f: read %d bytes\n", res);
if (res < 0) {
printf("f: this was an error: %s\n", strerror(errno));
} else {
printf("f: read: %.*s", res, buffer);
}
pthread_exit(NULL);
}
int main()
{
pthread_t t;
int res = pthread_create(&t, NULL, f, NULL);
printf("main: waiting 10 seconds\n");
sleep(10);
printf("main: closing stdin\n");
close(0);
printf("main: waiting another 10s.\n");
sleep(10);
printf("main: waiting for thread.\n");
pthread_join(t, NULL);
printf("main: reading from stdin\n");
res = read(0, buffer, sizeof buffer);
printf("main: read %d bytes\n", res);
if (res < 0) {
printf("main: this was an error: %s\n", strerror(errno));
} else {
printf("main: read: %.*s", res, buffer);
}
printf("main: exiting.\n");
}
Этот код приводит к следующей последовательности:
$ a.out
main: waiting 10 seconds
f: waiting on read()
main: closing stdin <--- now the fd is closed
main: waiting another 10s.
lorem ipsum <--- input
f: read 12 bytes
f: read: lorem ipsum
f: waiting on read()
f: read -1 bytes <--- file descriptor is not valid in the second read(2) call.
f: this was an error: Bad file descriptor
main: waiting for thread. <--- joining thread f
main: reading from stdin
main: read -1 bytes <--- invalid also for main thread.
main: this was an error: Bad file descriptor
main: exiting.
person
Luis Colorado
schedule
28.03.2017
close
. - person n. 1.8e9-where's-my-share m.   schedule 27.03.2017