получите стек вызовов и имейте его, выполняются в другом потоке

Я должен записать регистрирующийся API, который делает фактическое вхождение в систему отдельного потока.

т.е. у Меня есть приложение, которое хочет зарегистрировать некоторую информацию. Это называет мой API, и API получает все аргументы и т.д. и затем передает это к отдельному потоку, который будет зарегистрирован.

API регистратора принимает variadic аргументы, и поэтому мои начальные мысли состояли в том, чтобы получить целый стек вызовов и так или иначе вручить его потоку, который сделает вход.

Я разумен счастливый, что я могу получить стек вызовов. Однако я не уверен, как я выдал бы этот стек вызовов к другому методу.

Я использую g ++ на Linux, и ему, вероятно, также придется работать с CC v12 Sun на solaris.

Любые идеи.

1
задан ScaryAardvark 13 July 2010 в 09:25
поделиться

3 ответа

Вы можете захватить фиксированное количество байт на стеке вызовов, но вам придется копировать всю эту память, даже когда в ней нет необходимости, и помещать ее в какую-то очередь, чтобы передать потоку протоколирования. Кажется, что для этого нужно проделать много работы, и это довольно неэффективно.

Я предполагаю, что вы используете отдельный поток протоколирования, чтобы сделать API протоколирования более эффективным. Вполне вероятно, что в этом случае эффективнее, чтобы API протоколирования извлекал переменные параметры, преобразовывал их в более простое представление (например, в строку для протоколирования) и ставил в очередь.

Заметим также, что хороший API протоколирования не должен блокироваться, поэтому я бы посоветовал создать очередь без блокировок между API протоколирования и потоком протоколирования.

2
ответ дан 2 September 2019 в 23:06
поделиться

Проблема в том, что вы не знаете, как передать ее другому потоку, самое простое - это иметь очередь (std::deque, вероятно) стеков вызовов с мьютексом, защищающим ее. Когда ваше приложение генерирует стек вызовов, оно блокирует мьютекс, передает стек вызовов дальше и разблокирует мьютекс. Поток протоколирования периодически блокирует мьютекс, проверяет размер очереди, и если она не пуста, снимает стек вызовов и обрабатывает его.

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

0
ответ дан 2 September 2019 в 23:06
поделиться

Альтернативный подход может быть следующим:

  1. Определите макрос, который печатает имя функции и некоторую дополнительную информацию, такую как имя файла, номер строки и т.д., используя стандартные предопределенные макросы. Вы даже можете передать некоторую дополнительную информацию журнала, для которой в противном случае вы бы использовали printf. Это вызовет функцию для отправки данных в другой поток. Этот поток может ждать на сокете/трубе. Запишите данные в него, а затем вы можете читать из него, используя системные вызовы (write/read/pipe).
  2. Теперь вставьте этот макрос в начало каждой функции/API. Вы сможете получить поток вызовов (стек вызовов)
  3. Ваш поток регистрации может использовать информацию из этого макроса для записи в файл, вывода на консоль и т.д.

    define PRINT_LOG(X) function_to_pass_data_to_thread(X,FILE,LINE);

     API1()
    {
     PRINT_LOG("Entered API1");
     //Ваш API здесь
    

    }

PS: Извините за некачественное редактирование. Я не могу понять, в чем проблема с редактором. Думаю, нужно зарегистрировать ошибку в SO;)

.
0
ответ дан 2 September 2019 в 23:06
поделиться