есть ли метод isAlive в C для проверки состояния потока? [Дубликат]

2017 Ответ - pandas 0.20: .ix устарел. Использовать .loc

См. устаревание в документах

.loc использует индексирование на основе меток для выбора строк и столбцов. Метки являются значениями индекса или столбцов. Нарезка с .loc включает последний элемент.

Предположим, что у нас есть DataFrame со следующими столбцами: foo, bar, quz, ant, cat, sat, dat.

blockquote>
# selects all rows and all columns beginning at 'foo' up to and including 'sat'
df.loc[:, 'foo':'sat']
# foo bar quz ant cat sat

.loc принимает ту же самую нотацию фрагментов, что и списки Python для строк и столбцов. Обозначение фрагмента: start:stop:step

# slice from 'foo' to 'cat' by every 2nd column
df.loc[:, 'foo':'cat':2]
# foo quz cat

# slice from the beginning to 'bar'
df.loc[:, :'bar']
# foo bar

# slice from 'quz' to the end by 3
df.loc[:, 'quz'::3]
# quz sat

# attempt from 'sat' to 'bar'
df.loc[:, 'sat':'bar']
# no columns returned

# slice from 'sat' to 'bar'
df.loc[:, 'sat':'bar':-1]
sat cat ant quz bar

# slice notation is syntatic sugar for the slice function
# slice from 'quz' to the end by 2 with slice function
df.loc[:, slice('quz',None, 2)]
# quz cat dat

# select specific columns with a list
# select columns foo, bar and dat
df.loc[:, ['foo','bar','dat']]
# foo bar dat

Вы можете срезать по строкам и столбцам. Например, если у вас есть 5 строк с метками v, w, x, y, z

# slice from 'w' to 'y' and 'foo' to 'ant' by 3
df.loc['w':'y', 'foo':'ant':3]
#    foo ant
# w
# x
# y

39
задан Trevor Boyd Smith 28 January 2010 в 18:01
поделиться

6 ответов

Похоже, у вас есть два вопроса:

Как я могу подождать, пока мой поток не завершится?

Ответ: Это напрямую поддерживается pthreads - сделайте свой поток -be-stop JOINABLE (при первом запуске) и использовать pthread_join (), чтобы заблокировать текущий поток до тех пор, пока поток, который будет остановлен, больше не будет запущен.


Как я могу скажите, работает ли мой поток?

Ответ: вы можете добавить флаг «thread_complete», чтобы выполнить трюк:

Сценарий: Thread A хочет знать, жив ли Thread B .

Когда создается поток B, ему присваивается указатель на флаг «thread_complete». Флаг «thread_complete» должен быть инициализирован до NOT_COMPLETED до создания потока. Функция точки входа Thread B должна немедленно вызвать pthread_cleanup_push (), чтобы нажать «обработчик очистки», который устанавливает флаг «thread_complete» в COMPLETED.

Подробнее о обработчиках очистки см. Здесь: обработчики очистки pthread

Вы хотите включить соответствующий вызов pthread_cleanup_pop (1), чтобы гарантировать, что обработчик очистки будет вызван независимо от того, что (т. е. если поток нормально выходит из строя ИЛИ из-за отмены и т. д.).

Затем Thread A может просто проверить флаг «thread_complete», чтобы увидеть, еще ли вышел поток B.

ПРИМЕЧАНИЕ. Ваш флаг «thread_complete» должен быть объявлен «изменчивым» и должен быть атомный тип - компиляторы GNU предоставляют sig_atomic_t для этой цели. Это позволяет двум потокам согласовывать одни и те же данные без необходимости в конструкциях синхронизации (мьютексы / семафоры).

33
ответ дан jeremytrimble 21 August 2018 в 15:59
поделиться
  • 1
    Обработчики очистки полностью не нужны, если вы не будете использовать отмену (что обычно является довольно опасным инструментом). Кроме того, вы можете использовать переменную условия pthread вместе с переменной флага, чтобы включить ее, не вращая и не сжигая циклы процессора. – R.. 13 January 2011 в 02:09
  • 2
    Если цель состоит в том, чтобы знать, нужно ли или нет соединить соединение с "destroy" дескриптор pthread_t, проверка флага не будет работать, потому что поток может не завершиться, когда вы проверяете флаг, но все же можете завершить его до его объединения (обратите внимание, что объединение связанного потока приводит к неопределенному поведению и оставляет Непроницаемая соединительная нить приводит к утечке.) – Emil 29 September 2015 в 05:28
  • 3
    Всем, кто хочет использовать вышеупомянутое решение, я ответил ниже с проблемой с этим решением. Прочтите его, прежде чем применять его в своем решении. Это может быть не проблема во многих случаях, но вы можете узнать об этом. – newhouse 26 September 2016 в 11:25
  • 4
    @Emil Нет проблем. Просто не забудьте позвонить в один раз и только один раз. Гонка безвредна - да, ваше соединение может блокироваться на крошечную долю секунды, если вам случится проверить флаг после его установки и до того, как поток завершится, но поток вот-вот прекратится. – David Schwartz 26 September 2016 в 11:30
pthread_kill(tid, 0);

Сигнал не отправляется, но проверка ошибок по-прежнему выполняется, поэтому вы можете использовать это для проверки существования tid.

ВНИМАНИЕ: этот ответ неверен. В стандарте конкретно запрещается передавать идентификатор потока, срок службы которого закончился. Этот идентификатор теперь может указывать другой поток или, что еще хуже, он может ссылаться на освобожденную память, вызывая сбой.

29
ответ дан David Schwartz 21 August 2018 в 15:59
поделиться
  • 1
    По моей проблеме, это было именно то, что мне нужно было решить, спасибо. Я использовал (pthread_kill (tid, 0)! = ESRCH). – leetNightshade 26 October 2012 в 16:21
  • 2
    Обратите внимание: stackoverflow.com/questions/1693180/… – Qiu Yangfan 13 June 2015 в 14:12
  • 3
    @DavidSchwartz В таких случаях лучше пометить ваше редактирование как нечто, что не является частью исходного ответа, как предлагается здесь . – Dev-iL 20 March 2017 в 22:43

Не существует полностью портативного решения, посмотрите, поддерживает ли ваша платформа pthread_tryjoin_np или pthread_timedjoin_np. Поэтому вы просто проверяете, может ли поток быть присоединен (конечно, созданный с помощью PTHREAD_CREATE_JOINABLE).

5
ответ дан Dewfy 21 August 2018 в 15:59
поделиться
  • 1
    Эти интерфейсы были отклонены POSIX и не должны использоваться в приложениях, предназначенных для переносимости. То же самое можно выполнить с помощью переменной состояния. – R.. 13 January 2011 в 02:11
  • 2
    Просто потому, что одно и то же может быть выполнено с помощью переменной условия, не означает, что pthread_tryjoin_np не является более чистым интерфейсом. – Hubert Kario 9 January 2012 в 22:40

Я думаю, что вам действительно нужно называть pthread_join (). Этот вызов не будет возвращен до тех пор, пока поток не выйдет.

Если вы хотите только опросить, будет ли поток работать или нет (и обратите внимание, что обычно это не то, что вам нужно делать! ), у вас может быть поток, задающий volatile boolean на false, прежде чем он выйдет ... тогда ваш основной поток мог бы прочитать логическое значение, и если это все еще верно, вы знаете, что поток все еще работает. (если это ложь, с другой стороны, вы знаете, что поток, по крайней мере, почти ушел, он все равно может запускать код очистки, который возникает после того, как он устанавливает логическое значение в false, хотя, тем не менее, даже в этом случае вам все равно следует вызвать pthread_join before пытаясь освободить любые ресурсы, к которым у потока может быть доступ)

8
ответ дан Jeremy Friesner 21 August 2018 в 15:59
поделиться
  • 1
    +1 для объяснения потенциального состояния гонки и простого решения. – R.. 13 January 2011 в 02:10
  • 2
    «тогда ваш основной поток мог бы прочитать логическое значение, и если он по-прежнему верен, вы знаете, что поток все еще работает. & quot; - В этом случае вы только знаете, был ли поток выведен или нет, что не то же самое, что все еще работает или нет. – user470379 13 January 2011 в 22:14
  • 3
    Хм, у меня, вероятно, отсутствует возможность здесь, но AFAICT поток либо все еще работает, либо он вышел, либо он разбился. И если поток потерпел крушение, он взял на себя всю оставшуюся часть процесса, так что во втором случае все еще нет второго потока, чтобы обнаружить это. – Jeremy Friesner 3 February 2013 в 06:30

Позвольте мне отметить «выигрышный» ответ, который имеет огромный скрытый недостаток, и в некоторых контекстах это может привести к сбоям. Если вы не используете pthread_join, он будет появляться снова и снова. Предположим, что у вас есть процесс и общая библиотека. Вызовите библиотеку lib.so.

  1. Вы закрываете ее, вы начинаете в ней нить. Предположим, вы не хотите, чтобы он присоединился к нему, поэтому вы установите его съемным.
  2. Логика процесса и общей библиотеки lib и т. Д. ...
  3. Вы хотите загрузить lib .so, потому что вам это больше не нужно.
  4. Вы вызываете выключение по потоку, и вы говорите, что вы хотите прочитать флаг после этого из потока lib.so, который он закончил .
  5. Вы продолжаете в другом потоке с dlclose, потому что видите, что вы видели, что флаг теперь показывает поток как «законченный»
  6. dlclose будет загружать весь стек и память, связанная с кодом.
  7. Whops, но dlclose не останавливает потоки. И вы знаете, даже когда вы находитесь в последней строке обработчика очистки, чтобы установить «поток завершен» изменчивой переменной атомного флага, вам все равно придется возвращаться из множества методов в стеке, возвращая значения и т. Д. Если приоритет огромного потока был задан нитью # 5 + # 6, вы получите dlclose, прежде чем сможете ДЕЙСТВИТЕЛЬНО остановить поток. Иногда у вас будут какие-то приятные сбои.

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

0
ответ дан newhouse 21 August 2018 в 15:59
поделиться
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>

void* thread1 (void* arg);
void* thread2 (void* arg);

int main()
{
    pthread_t thr_id;

    pthread_create(&thr_id, NULL, thread1, NULL);

    sleep(10);
}

void* thread1 (void* arg)
{
    pthread_t thr_id = 0;

    pthread_create(&thr_id, NULL, thread2, NULL);

    sleep(5);
    int ret = 0;
    if( (ret = pthread_kill(thr_id, 0)) == 0)
    {
        printf("still running\n");
        pthread_join(thr_id, NULL);
    }
    else
    {
        printf("RIP Thread = %d\n",ret);
    }
}

void* thread2 (void* arg)
{
//  sleep(5);
    printf("I am done\n");
}
-1
ответ дан Priyesh Shah Pilu 21 August 2018 в 15:59
поделиться
  • 1
    Хотя этот код может ответить на вопрос, предоставляя дополнительный контекст относительно того, почему и / или как этот код отвечает на вопрос, улучшает его долгосрочную ценность. – JAL 23 October 2015 в 23:51
  • 2
    Возможно, вы не знаете, но выполнение pthread_kill в мертвой ветке потенциально может привести к краху вашего приложения или вызвать неожиданные результаты, такие как освобождение памяти, используемой для чего-то еще. stackoverflow.com/a/1693235/105539 – Volomike 1 April 2016 в 07:32
Другие вопросы по тегам:

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