Поточная обработка Windows: _beginthread по сравнению с _beginthreadex по сравнению с CreateThread C++

Использование:

function sortArguments() {
  return arguments.length === 1 ? [arguments[0]] :
                 Array.apply(null, arguments).sort();
}

Array(arg1, arg2, ...) возвращает [arg1, arg2, ...]

Array(str1) возвращается [str1]

Array(num1) возвращает массив, который имеет num1 элементы

Вы должны проверить количество аргументов!

Array.slice версия (медленнее):

function sortArguments() {
  return Array.prototype.slice.call(arguments).sort();
}

Array.push версия (медленнее , быстрее, чем срез):

function sortArguments() {
  var args = [];
  Array.prototype.push.apply(args, arguments);
  return args.sort();
}

Переместить версию (медленнее, но малый размер быстрее):

function sortArguments() {
  var args = [];
  for (var i = 0; i < arguments.length; ++i)
    args[i] = arguments[i];
  return args.sort();
}

Array.concat версия (самая медленная):

function sortArguments() {
  return Array.prototype.concat.apply([], arguments).sort();
}
130
задан MD XF 9 May 2017 в 03:02
поделиться

6 ответов

CreateThread() необработанный вызов API Win32 создания другого потока управления на уровне ядра.

_beginthread() & _beginthreadex() вызовы библиотеки времени выполнения C тот вызов CreateThread() негласно. Однажды CreateThread() возвратился, _beginthread/ex() заботится о дополнительной бухгалтерии для создания библиотеки времени выполнения C применимым & последовательный в новом потоке.

В C++ необходимо почти наверняка использовать _beginthreadex(), если Вы не будете связываться с библиотекой времени выполнения C вообще (иначе MSVCRT*.dll/.lib).

94
ответ дан 24 November 2019 в 00:25
поделиться

Относительно Вашего обновленного вопроса: "Я также читал в нескольких местах, которые я не могу назвать WaitForSingleObject(), если я использовал _beginthread(), но если я звоню _endthread() в поток разве, который не должен работать?"

В целом, можно передать дескриптор потока WaitForSingleObject() (или другие API, которые ожидают на объектных дескрипторах) заблокироваться, пока поток не завершился. Но дескриптор потока, созданный _beginthread(), закрывается, когда _endthread() назван (который может быть сделан явно или сделан неявно ко времени выполнения, когда процедура потока возвращается).

проблема вызывается в документации для WaitForSingleObject():

, Если этот дескриптор закрывается, в то время как ожидание все еще находится на рассмотрении, поведение функции не определено.

5
ответ дан 24 November 2019 в 00:25
поделиться

beginthreadex дает Вам поток HANDLE для использования в WaitForSingleObject и друзья. beginthread не делает. Не забывайте к CloseHandle(), когда Вы будете сделаны. Реальный ответ должен был бы использовать boost::thread или скоро класс потока 09 C++.

3
ответ дан 24 November 2019 в 00:25
поделиться

CreateThread() раньше имел утечки памяти , когда Вы используете любые функции CRT в своем коде. _beginthreadex() имеет те же параметры как CreateThread(), и это более универсально, чем _beginthread(). Таким образом, я рекомендую использовать _beginthreadex().

8
ответ дан 24 November 2019 в 00:25
поделиться

Это - код в ядре _beginthreadex (см. crt\src\threadex.c):

    /*
     * Create the new thread using the parameters supplied by the caller.
     */
    if ( (thdl = (uintptr_t)
          CreateThread( (LPSECURITY_ATTRIBUTES)security,
                        stacksize,
                        _threadstartex,
                        (LPVOID)ptd,
                        createflag,
                        (LPDWORD)thrdaddr))
         == (uintptr_t)0 )
    {
            err = GetLastError();
            goto error_return;
    }

Остальная часть _beginthreadex инициализирует структуру данных на поток для CRT.

преимущество использования _beginthread* состоит в том, что Ваши вызовы CRT от потока будут работать правильно.

17
ответ дан 24 November 2019 в 00:25
поделиться

Существует несколько различий между _beginthread() и _beginthreadex(). _beginthreadex() был сделан действовать больше как CreateThread() (в обоих параметрах и как это ведет себя).

Как [1 115] Drew Hall упоминает, если Вы используете время выполнения C/C++, необходимо использовать _beginthread() / _beginthreadex() вместо CreateThread() так, чтобы время выполнения имело шанс выполнить свою собственную инициализацию потока (настраивающий локальную память потока, и т.д.).

На практике, это означает, что CreateThread() никогда не должен в значительной степени использоваться непосредственно Вашим кодом.

документы MSDN для _beginthread() / _beginthreadex() имеют довольно мало детали о различиях - один из более важных - то, что, так как дескриптор потока для потока, созданного [1 111], закрывается автоматически CRT, когда поток выходит, "если поток, сгенерированный выходами _beginthread быстро, дескриптор, возвращенный вызывающей стороне _beginthread, мог бы быть недопустимым или, хуже, укажите на другой поток".

Вот то, что должны сказать комментарии для [1 112] в источнике CRT:

Differences between _beginthread/_endthread and the "ex" versions:

1)  _beginthreadex takes the 3 extra parameters to CreateThread
  which are lacking in _beginthread():
    A) security descriptor for the new thread
    B) initial thread state (running/asleep)
    C) pointer to return ID of newly created thread

2)  The routine passed to _beginthread() must be __cdecl and has
  no return code, but the routine passed to _beginthreadex()
  must be __stdcall and returns a thread exit code.  _endthread
  likewise takes no parameter and calls ExitThread() with a
  parameter of zero, but _endthreadex() takes a parameter as
  thread exit code.

3)  _endthread implicitly closes the handle to the thread, but
  _endthreadex does not!

4)  _beginthread returns -1 for failure, _beginthreadex returns
  0 for failure (just like CreateThread).

Обновление Jan 2013:

CRT для VS 2012 имеет дополнительный бит инициализации, выполненной в [1 113]: если процесс будет "пакетным приложением" (если что-то полезное будет возвращено от [1 114]), то время выполнения инициализирует MTA на недавно созданном потоке.

36
ответ дан 24 November 2019 в 00:25
поделиться