Reputation: 128
Using pthreads, I created a thread that does audio recording through shell:
void *thread_function(void *arg) {
system("arecord data.wav");
}
However, when I call pthread_cancel(&thread_ID);
to terminate the thread, the audio recorder still works on its own (Until I terminate the whole C program of course).
How do I stop a pthread that does a system call? Thanks in advance!
Upvotes: 0
Views: 234
Reputation: 56519
system("arecord data.wav");
It will make a separate process (not a thread in your program) in your system, and terminating that thread will not affect that process. You should kill that process by another system call.
However making the process with spawn* functions in non-waiting mode is a bit better than your way and in this case and you don't need an extra thread.
spawnl(P_NOWAIT, "arecord data.wav", .... );
But, killing the created process is ugly.
Upvotes: 1
Reputation: 215457
Your thread start function should do the following:
pid_t pid;
int status;
posix_spawnp(&pid, "arecord", 0, 0, (char *[]){"arecord", "data.wav", 0}, environ);
pthread_cleanup_push(cleanup, &pid);
while (waitpid(pid, &status, 0)<0 && errno==EINTR);
pthread_cleanup_pop(0);
With a cleanup function like:
static void cleanup(void *p)
{
pid_t pid = *(pid_t *)p;
kill(pid, SIGTERM);
while (waitpid(pid, &status, 0)<0 && errno==EINTR);
}
Then cancelling the thread with pthread_cancel
will kill the child process.
Upvotes: 2
Reputation: 10073
You can use pthread_kill
to send a signal to a specific thread. The problem with thread cancellation is that it will be delayed until the program reaches a cancellation point (see this answer).
If you do use pthread_kill
then you can choose which signal to send. I think it should be possible to end the thread with a kill signal which would then also end the child process spawned with system, although I'm not certain about that.
Upvotes: 0