fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 09:36
Оценка:
#include <io.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <assert.h>

int 
_tmain(int argc, _TCHAR* argv[]) 
{

    for (size_t i = 0; i < 5000; ++ i) {
        std::cout << "i = " << i << std::endl;

    FILE *pFile  = fopen("C:/Test.txt", "w+");
        assert(NULL != pFile);

        int   iFile = fileno(pFile);      
        assert(- 1 != iFile);
        
        errno = 0;
        FILE *pFile2 = fdopen(iFile, "w+");
        if (NULL == pFile2) {
                std::cout << strerror(errno) << std::endl;
            std::cout << "NULL == pFile2 (" << strerror(errno) << ")" << std::endl;
                assert(false);
        }

        fclose(pFile);
    }

    return 0;
}



---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Error!

Program: C:\TempFile 2\Debug\TempFile.exe

R6010

- abort() has been called



(Press Retry to debug the application)
---------------------------
Прервать   Повтор   Пропустить   
---------------------------



Вывод:
i = 0
i = 1
...
i = 506
i = 507
i = 508
Too many open files
NULL == pFile2 (Too many open files)

Что не так?
Re: fdopen - Too many open files
От: Vain Россия google.ru
Дата: 28.08.11 09:45
Оценка:
Здравствуйте, Alca, Вы писали:
        fclose(pFile2); //?
        fclose(pFile);

A>Что не так?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: fdopen - Too many open files
От: genok Россия  
Дата: 28.08.11 09:46
Оценка:
Здравствуйте, Alca, Вы писали:

A>Вывод:

A>
A>i = 0
A>i = 1
A>...
A>i = 506
A>i = 507
A>i = 508
A>Too many open files
A>NULL == pFile2 (Too many open files)
A>

A>Что не так?

все так. система имеет предел на количество открытых дескрипторов. причем не только файлов, но и дескрипторов других ресурсов
Re[2]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 09:56
Оценка:
я ж их как-бы закрываю
Re[2]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 09:59
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, Alca, Вы писали:

V>
V>        fclose(pFile2); //?
V>        fclose(pFile);
V>

A>>Что не так?


        fclose(pFile);
        fclose(pFile2);



---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!

Program: C:\TempFile 2\Debug\TempFile.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\close.c
Line: 47

Expression: (_osfile(fh) & FOPEN)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)
---------------------------
Прервать   Повтор   Пропустить   
---------------------------
Re: fdopen - Too many open files
От: genok Россия  
Дата: 28.08.11 10:06
Оценка:
Здравствуйте, Alca, Вы писали:

A>
A>#include <io.h>
A>#include <string.h>
A>#include <stdio.h>
A>#include <iostream>
A>#include <assert.h>

A>int 
A>_tmain(int argc, _TCHAR* argv[]) 
A>{

A>    for (size_t i = 0; i < 5000; ++ i) {
A>        std::cout << "i = " << i << std::endl;

A>    FILE *pFile  = fopen("C:/Test.txt", "w+");
A>        assert(NULL != pFile);

A>        int   iFile = fileno(pFile);      
A>        assert(- 1 != iFile);
        
A>        errno = 0;
A>        FILE *pFile2 = fdopen(iFile, "w+");
A>        if (NULL == pFile2) {
A>                std::cout << strerror(errno) << std::endl;
A>            std::cout << "NULL == pFile2 (" << strerror(errno) << ")" << std::endl;
A>                assert(false);
A>        }

A>        fclose(pFile);
A>    }

A>    return 0;
A>}
A>



A>
A>---------------------------
A>Microsoft Visual C++ Debug Library
A>---------------------------
A>Debug Error!

A>Program: C:\TempFile 2\Debug\TempFile.exe

A>R6010

A>- abort() has been called



A>(Press Retry to debug the application)
A>---------------------------
A>Прервать   Повтор   Пропустить   
A>---------------------------
A>



A>Вывод:

A>
A>i = 0
A>i = 1
A>...
A>i = 506
A>i = 507
A>i = 508
A>Too many open files
A>NULL == pFile2 (Too many open files)
A>

A>Что не так?

ты открываешь файл два раза — один по имени, другой по номеру. получаешь два дескриптора. закрываешь только один
Re: fdopen - Too many open files
От: genok Россия  
Дата: 28.08.11 10:21
Оценка:
Здравствуйте, Alca, Вы писали:

A>
A>#include <io.h>
A>#include <string.h>
A>#include <stdio.h>
A>#include <iostream>
A>#include <assert.h>

A>int 
A>_tmain(int argc, _TCHAR* argv[]) 
A>{

A>    for (size_t i = 0; i < 5000; ++ i) {
A>        std::cout << "i = " << i << std::endl;

A>    FILE *pFile  = fopen("C:/Test.txt", "w+");
A>        assert(NULL != pFile);

A>        int   iFile = fileno(pFile);      
A>        assert(- 1 != iFile);
        
A>        errno = 0;
A>        FILE *pFile2 = fdopen(iFile, "w+");
A>        if (NULL == pFile2) {
A>                std::cout << strerror(errno) << std::endl;
A>            std::cout << "NULL == pFile2 (" << strerror(errno) << ")" << std::endl;
A>                assert(false);
A>        }

A>        fclose(pFile);
A>    }

A>    return 0;
A>}
A>



A>
A>---------------------------
A>Microsoft Visual C++ Debug Library
A>---------------------------
A>Debug Error!

A>Program: C:\TempFile 2\Debug\TempFile.exe

A>R6010

A>- abort() has been called



A>(Press Retry to debug the application)
A>---------------------------
A>Прервать   Повтор   Пропустить   
A>---------------------------
A>



A>Вывод:

A>
A>i = 0
A>i = 1
A>...
A>i = 506
A>i = 507
A>i = 508
A>Too many open files
A>NULL == pFile2 (Too many open files)
A>

A>Что не так?

был не прав, исправляюсь:
The file descriptor is not dup'ed, and will be closed when the stream created by fdopen() is closed.

итого, да, открывается только один дескриптор и по закрытию fclose(pFile2); он должен закрыться. второго fclose не нужно
Re[2]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 10:23
Оценка:
а почему тогда "Too many open files"?
Re[3]: fdopen - Too many open files
От: genok Россия  
Дата: 28.08.11 10:36
Оценка:
Здравствуйте, Alca, Вы писали:

A>а почему тогда "Too many open files"?


может потому что твоим вызовом дескриптор не может быть закрыт и закрыть нужно именно pFile2?
Re[4]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 10:47
Оценка:
fclose(pFile2)

таже шняга, что и раньше — Too many open files
Re[5]: fdopen - Too many open files
От: genok Россия  
Дата: 28.08.11 10:53
Оценка:
Здравствуйте, Alca, Вы писали:

A>
A>fclose(pFile2)
A>

A>таже шняга, что и раньше — Too many open files

попробовал у себя на дебиане оба варианта. все отрабатывает на ура в обоих вариантах даже при счетчике цикла = 500 000
Re: fdopen - Too many open files
От: dilmah США  
Дата: 28.08.11 11:12
Оценка:
A>Что не так?

есть 2 слоя -- целочисленные дескрипторы предоставляемые ОС и FILE структуры предоставляемые libc.
У тебя 2 структуры FILE используюшие один дескриптор.
Очевидно, что libc ведет подсчет -- сколько структур ссылается на дескриптор, и закрывает дескриптор ОС только когда не осатется структур FILE ссылающихся на него.
Очевидно, что нужно закрыть обе структуры FILE
Re[6]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 13:08
Оценка:
Так у меня на линухах и фрях тоже работает, а вот на винде...
Re[2]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 13:10
Оценка:
Здравствуйте, dilmah, Вы писали:


A>>Что не так?


D>есть 2 слоя -- целочисленные дескрипторы предоставляемые ОС и FILE структуры предоставляемые libc.

D>У тебя 2 структуры FILE используюшие один дескриптор.
D>Очевидно, что libc ведет подсчет -- сколько структур ссылается на дескриптор, и закрывает дескриптор ОС только когда не осатется структур FILE ссылающихся на него.
D>Очевидно, что нужно закрыть обе структуры FILE

http://www.rsdn.ru/forum/cpp/4397774.1.aspx
Автор: Alca
Дата: 28.08.11
Re: fdopen - Too many open files
От: Vain Россия google.ru
Дата: 28.08.11 15:28
Оценка:
Здравствуйте, Alca, Вы писали:

A>Что не так?

Попробуйте вот так:
#include <windows.h>
#include <io.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <xiosbase>
#include <fcntl.h>

int main(int argc, char* argv[]) 
{
  HANDLE hStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  HANDLE hStdHandleCopy = 0;
  if(!DuplicateHandle(GetCurrentProcess(), hStdHandle, GetCurrentProcess(), &hStdHandleCopy, 0, FALSE, DUPLICATE_SAME_ACCESS))
  {
    assert(false);
  }
  int hConHandle = _open_osfhandle((intptr_t)hStdHandleCopy, _O_TEXT);
  FILE* stdinCopy = _fdopen(hConHandle, "w");

  printf("111\n");

  errno = 0;
  FILE* pFile = _wfreopen(L"C:/Test.txt", L"w+", stdout);
  if (NULL == pFile) {
    std::cout << strerror(errno) << std::endl;
    std::cout << "NULL == pFile2 (" << strerror(errno) << ")" << std::endl;
    assert(false);
    return 1;
  }

  for (size_t i = 0; i < 5000; ++ i) {
    std::cout << "i = " << i << std::endl;
  }

  fclose(pFile);

  // redirect unbuffered STDOUT to the console

  *stdout = *stdinCopy;

  setvbuf( stdout, NULL, _IONBF, 0 ); // no buffering

  //std::ios::sync_with_stdio();

  printf("222\n");
  std::cout << "333" << std::endl;

  if(!CloseHandle(hStdHandleCopy))
  {
    assert(false);
  }

  return 0;
}

нашёл здесь.
PS: Похоже стандартный хендл (FILE) надо закрывать, только вот, к примеру, _freopen закрывает вместе с ним и системный (HANDLE), а таблица CRT дескрипторов открытых функцией _open_osfhandle с системных — ещё меньше чем количество разрешённых FILE-хендлов. К примеру, под VS2005 их вообще 64 штуки (см. макрос IOINFO_ARRAYS и вызов функции _alloc_osfhnd из функции _open_osfhandle в файле osfinfo.c)
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 15:37
Оценка:
#include <windows.h>
#include <io.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <xiosbase>
#include <fcntl.h>

int 
main(int argc, char* argv[]) 
{
    for (size_t i = 0; i < 5000; ++ i) {
        HANDLE hStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
        HANDLE hStdHandleCopy = 0;
        if (!DuplicateHandle(GetCurrentProcess(), hStdHandle, GetCurrentProcess(), &hStdHandleCopy, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
            assert(false);
        }
        int hConHandle = _open_osfhandle((intptr_t)hStdHandleCopy, _O_TEXT);
        FILE* stdinCopy = _fdopen(hConHandle, "w");

        printf("111\n");

        errno = 0;
        FILE* pFile = _wfreopen(L"C:/Test.txt", L"w+", stdout);
        if (NULL == pFile) {
            std::cout << strerror(errno) << std::endl;
            std::cout << "NULL == pFile2 (" << strerror(errno) << ")" << std::endl;
            assert(false);

            return 1;
        }
      
        std::cout << "i = " << i << std::endl;

        fclose(pFile);

        // redirect unbuffered STDOUT to the console
        *stdout = *stdinCopy;

        setvbuf( stdout, NULL, _IONBF, 0 ); // no buffering

        //std::ios::sync_with_stdio();

        printf("222\n");
        std::cout << "333" << std::endl;

        if (!CloseHandle(hStdHandleCopy)) {
            assert(false);
        }
    }

    return 0;
}


111                                                                                                                                                                                                     
222                                                                                                                                                                                                     
333                                                                                                                                                                                                     
Assertion failed: false, file c:\tempfile 3\tempfile.cpp, line 17


---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Error!

Program: C:\TempFile 3\Debug\TempFile.exe

R6010

- abort() has been called



(Press Retry to debug the application)
---------------------------
Прервать   Повтор   Пропустить   
---------------------------
Re[3]: fdopen - Too many open files
От: Vain Россия google.ru
Дата: 28.08.11 15:51
Оценка:
A>
A>111                                                                                                                                                                                                     
A>222                                                                                                                                                                                                     
A>333                                                                                                                                                                                                     
A>Assertion failed: false, file c:\tempfile 3\tempfile.cpp, line 17   
A>

А зачем ты цикл вынес наружу?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 16:18
Оценка:
V>А зачем ты цикл вынес наружу?

а зечем он внутри? Цикл снаружи — это типа тест.
Re[5]: fdopen - Too many open files
От: Vain Россия google.ru
Дата: 28.08.11 16:20
Оценка:
Здравствуйте, Alca, Вы писали:

V>>А зачем ты цикл вынес наружу?

A>а зечем он внутри? Цикл снаружи — это типа тест.
А ты читал что я тебе написал?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[6]: fdopen - Too many open files
От: Alca Украина  
Дата: 28.08.11 16:21
Оценка:
где именно?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.