LINUX.ORG.RU

Как правильно запустить bash script в новом потоке?

 , , ,


1

1

Извиняюсь за, возможно, тупой вопрос, но что я делаю не так? Хочу запустить из прогаммы дополнительный параллельный поток, в котором выполнялся бы скрипт:

static void *scriptthreadFunc(void *arg)
{
  int result=execlp("bash","bash","Scenario.sh",NULL);
  printf("Script has been returned with code %d errno %d\r\n",result,errno); 
}

void ExecScript()
{

  int result=pthread_create(&scriptthread, NULL, scriptthreadFunc, NULL);
}
В итоге скрипт запускается, но вместо работы в параллельном потоке тормозит работу основной программы полностью. Что я делаю не так?


Ответ на: комментарий от joy4eg

int result=system(«Scenario.sh»);

С тем же результатом. Скрипт выполняется, остальные потоки тормозятся. (

MBK
() автор топика
Ответ на: комментарий от MBK

Но я не хочу через fork, мне надо в отдельном потоке

А без fork никак не выйдет. Тот же system - это fork + exec + wait. Очень странно, что при вызове system() у тебя блокируются другие треды. Должен засыпать только вызывающий.

Dead ★★★★
()
Ответ на: комментарий от Pinkbyte

покажи весь код, может у тебя там блокировок понатыкано

Код скрипта? Самый простецкий тестовый

#!/bin/bash

while :  # бесконечный цикл
 do
 sleep 1
 echo "Do script 1"
 
  
done

MBK
() автор топика
Ответ на: комментарий от MBK

нет, код того как ты его вызываешь. Вот есть у тебя функция execscript?

Кто её вызывает? Что там дальше? Может там блокировка, ждущая завершения треда?

Pinkbyte ★★★★★
()

exec - без форка в вашем примере не имеет смысла так как exec не порождает новых процессов, ТЕКУЩИЙ процесс ЗАМЕЩАЕТСЯ вызваным бинарником.

Тоесть вот выполняется ваша программа (PID 1001), она делает

execlp("bash","bash","Scenario.sh",NULL);
Все больше вашей программы нету, теперь под PID 1001 будет находится bash а вашей программы больше нету.

zaz ★★★★
()
Ответ на: комментарий от MBK

Что-то ты делаешь не так:

cat ./system.c

                                                       
#include <stdio.h>                                                                                                                                     
#include <pthread.h>                                                                                                                                   


void *thread_func(void *data)
{
        system("./sample_script.sh");
}


int main(void)
{
        pthread_t th;
        pthread_create(&th, NULL, thread_func, NULL);
         
         while (1)
         {
                 printf("I'm alive\n");
                 sleep(1);
         }


        return 0;
}

cat ./sample_script.sh

#!/bin/bash

while :  # бесконечный цикл
 do
 sleep 1
 echo "Do script 1"
 
done


./system
I'm alive
I'm alive
Do script 1
I'm alive
Do script 1
I'm alive
Do script 1
I'm alive
Do script 1
I'm alive
Do script 1
I'm alive
Do script 1
I'm alive
Do script 1
^C^C

Все работает, все стреляет (с)

Dead ★★★★
()
Последнее исправление: Dead (всего исправлений: 2)
Ответ на: комментарий от Dead

Уфф, разобрался, спасибо, тысячу извинений, точно, это я тормоз, через system все работает отлично! Теперь другой вопрос - как этот thread корректно прервать из вызывающей программы? pthread_cancel(scriptthread) сходу не сработало.

MBK
() автор топика
Ответ на: комментарий от MBK

Теперь другой вопрос - как этот thread корректно прервать из вызывающей программы?

ЕМНИП pthread_cancel не рекомендуется.
Лучше через флажки.
Но в случае с system() нужно сначала прервать его, например, через сигнал.
в простейшем случае :)
system(«killall sample_script.sh»);

Dead ★★★★
()
Ответ на: комментарий от Dead

Замечательно! Спасибо огромное, все работает как надо!

MBK
() автор топика
Ответ на: комментарий от Dead
system(«killall sample_script.sh»);

Какой только гадости на ЛОРе не посоветуют. Читая тут треды про Си, можно голову себе свернуть от негодования.

Во-первых, что будет, если работает несколько инстанций программы?

Во-вторых, правильнее было бы использовать fork+exec*+waitpid+kill.

Deleted
()
Ответ на: комментарий от Deleted

Какой только гадости на ЛОРе не посоветуют.
Во-первых, что будет, если работает несколько инстанций программы?

Я вас умаляю. Человек сам должен понимать о последствиях такого решения. Для embedded, например, вполне себе решение, когда точно знаешь чего и сколько запущено.

Dead ★★★★
()
Ответ на: комментарий от Deleted

Во-вторых, правильнее было бы использовать fork+exec*+waitpid+kill.

В общем случае, действительно так, ибо проблемы с секьюрностью и т.п. В embedded же в основном встречаю system(), там люди особо не заморачиваются :)

Dead ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.