Я пытаюсь проверить существование процесса в c++ с помощью потока. Я изначально тестировался без какой-либо темы и давал основную проверку на существование. Это сработало. Но вдруг, когда я поместил эту часть кода внутри потока, она не работает. Я озадачен, увидев, что он не работает. Может кто-нибудь, пожалуйста, скажите мне, почему часть кода не работает, когда дело доходит до его использования в потоке.
Моя первоначальная тестовая программа для существования процесса: составлена следующим образом: CC protest2.cc -o nothr
int main(int argc, char **argv)
{
struct stat sts;
string f=string("/proc/")+argv[1];
while(!(stat(f.c_str(), &sts) == -1 && errno == ENOENT))
{
cout<<"process exists"<<endl;
sleep(1);
}
cout<<"process Does not exist"<<endl;
return 0;
}
Небольшой процесс, который длится несколько секунд, а затем выходит.
int main() {
sleep(5);
for(int i=0;i<5;i++)
{
sleep(2);
}
}
Моя вторая тестовая программа для существования процесса с использованием потока (это не работает): Скомпилировано, как CC protest.cc -o thr
ниже: CC protest.cc -o thr
extern "C" void *run(void *str){
struct stat sts;
while(!(stat((char *)str, &sts) == -1 && errno == ENOENT))
{
cout<<"process exists"<<endl;
sleep(1);
}
return NULL;
}
int main(int argc,char **argv)
{
string f=string("/proc/")+argv[1];
pthread_t pid;
int res=pthread_create(&pid,NULL,run,(void *)f.c_str());
pthread_join(pid,NULL);
cout<<f<<endl;
cout<<"process Does not exist"<<endl;
return 0;
}
Вывод при отсутствии потока:
> ./a.out &
[1] 10128
> ./nothr 10128
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process Does not exist
[1] + Done ./a.out
>
Вывод, когда есть поток:
> ./thr 10458
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
process exists
^C
Он продолжается до тех пор, пока я не нажму CTRL + C.
Очень очень технически допустимое время жизни f.c_str()
(в вашем примере с резьбовым кодом) чисто на время вызова pthread_create
. Таким образом, в тот момент, когда поток вызывает stat
, содержимое переданного адреса изменилось достаточно, чтобы вы могли получить ошибку, ENOENT
от ENOENT
. который провалит ваш тест, и вы зациклитесь навсегда.
Попутно использование kill(pid, 0)
- гораздо более портативный и легкий способ тестирования для существования процесса.
while
условия цикла вы неоднократно вызываете!(stat((char *)str, &sts) == -1
с теми же параметрами. Таким образом, он зацикливается навсегда.