How to use C popen in a pthread - c

First, I've been reading some comments in forums about it's recommended to avoid using fork in threads, and popen does fork.
Anyway, I'm doing a program with some threads and it'll be very useful for me to using other library functions which execute popen.
When I do that, program exits.
Let me put a simple example because the code is large:
int main()
{
pthread_t thread1, thread2;
int var=1;
pthread_create(&thread1, NULL, mythread, &var);
pthread_create(&thread2, NULL, anotherthread, &var);
...
}
void *mythread(void *s)
{
...
pthread_detach(pthread_self());
...
printf("this is printed\n");
char *str = externalFunctWithPopen();
printf("this is NEVER printed\n");
...
}
char *externalFunctWithPopen()
{
...
printf("this is also printed\n");
popf = popen(command, "r");
printf("this is not printed at all\n");
while (fgets(buf, sizeof(buf), popf) != 0) {
...
}
As I told before, "this is NEVER printed" is never printed, and furthermore, main exits, including the other thread called anotherthread
Any piece of help is welcome.

main exits, including the other thread
To avoid the behaviour that leaving main() tears down all other threads of the same process. leave it via a call to pthread_exit() instead of doing exit() or just return.

Related

why isnt the code after pthread_join() executed?

I am writing a simple tcp client for an IRC server that I have. So Im implementing this by having a writer thread and a receiver thread, however after the user quits the session, the program stops all execution after the thread has been stopped and just presents a scanf()-like output in the console.
void senderThread(void* context){
for(;;){
//setup here
//gets user input and stores into char* msg
if(strcmp(msg, "quit") == 0){
printf("quitting...\n");
free(msg);
shutdown(clientdata->sockfd, SHUT_RDWR);
return NULL;
}else {
write(clientdata->sockfd, msg, strlen(msg));
write(clientdata->sockfd, "\n", strlen("\n"));
free(msg);
}
}
return NULL;
}
int main(int argc, char* argv[]){
//setup stuff here
pthread_t thread_id[1];
pthread_create(&thread_id[1], NULL, senderThread, (void *) &clientdata);
printf("creating threads...\n");
pthread_join(thread_id, NULL); //for(;;) loop here
shutdown(sockfd, SHUT_RDWR);
free(username);
return 0;
}
this is a part of the code for the program, however when I type 'quit' into the stdin, nothing happens. the printf and the shutdown both fire, but then I am left just left with the terminal expecting input and the program not actually closing. none of the code after the pthread_join() is executed. Why is this?
&thread_id[1] is a pointer to the second element in the one-element array. That will be out of bounds and lead to undefined behavior.
You then call pthread_join passing a pointer to the first and uninitialized element in the array. Again leading to undefined behavior.
I suggest you use a single pthread_t value (instead of an array), and use the address-of operator in both the pthread_create and the pthread_join calls:
pthread_t thread_id;
pthread_create(&thread_id, ...);
pthread_join(&thread_id, NULL);

Getting unwanted signals/input from terminal in c program

I written c program in the below concepts.
main_process.c
/* check the give process id is alive or not. if not alive then start that process.*/
void * thread1()
{
while(1) {
if (kill(pid, 0)!=0) {
system(process1);
}
}
}
/* Get the process id for the started process */
void *thread2() {
while (1) {
FILE *fp = popen("ps -af | grep "process1");
get_pid(pid, fp);
pclose(pid);
}
}
get_pid(pid, fp) {
/* Get the pid for the new process using getline() and string parsing using string token function, its long code so not pasted here.*/
}
main(int arg, char *args[]) {
pthread_t tid1, tid2;
pthread_create(tid1,NULL, &thread1, NULL);
pthread_create(tid2, NULL, &thread2, NULL);
//Checks thread created success or not.
pthread_join(tid1);
pthread_join(tid2);
}
process:
main() {
char input[100];
while (1) {
fgets(input, 100, stdin);
printf("\n Input is %s \n", input);
}
I started the process program first, and get the pid and starting the main_process.
After some time I killed the process program using kill -9 pid. So the if condition of thread1 in main_process passed and starts the process program.
Getting inputs from the terminal. After some time I again killed the process program using kill -9 pid. So thread1 again starts the process program.
Issue is the following: When the process program starts for the second time, getting unwanted inputs from terminal. I have no idea about who's sending, issue in keyboard or in my program concepts.
Please inform where I made mistakes.

Creating a thread which writes into a file

I am learning threads and trying to implement a code which creates a thread. The thread writes into a file. If the thread has been created it returns 0 . The code here returns 0 but it does go into the function write() but does not writes in the file . Just to check it goes in the function i have put a printf() statement.I want the input should be taken by command line here but it also does not work so to make it simpler i have written only "hello world" to the file .
Here is the code :-
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
void *write(void *arg)
{
printf("HI \n");
FILE *fp;
fp = fopen("file.txt", "a");
if (fp == NULL) {
printf("error\n");
} else {
fprintf(fp, "hello world");
}
}
int main()
{
pthread_t thread;
int tid;
tid = pthread_create(&thread, NULL, write, NULL);
printf("thread1 return %d \n", tid);
exit(0);
}
I suspect what's happening is the exit() call is executing before the fprintf() gets to the point of putting content into the buffer.
pthread_create() returns after creating the thread, not after the thread finishes, and then both threads run simultaneously. Maybe this is your first "race condition"?
void *result; pthread_join(tid, &result); will wait for the function running in the other thread to return (and get it's return value).
correction
Forgot that the file pointer is not automatically closed, so this will thwart you as well. Call fflush() or fclose() after the fprintf.
You need to join with the thread to wait for it to finish before exiting your main program.
tid=pthread_create(&thread,NULL,write,NULL);
printf("thread1 return %d \n",tid);
pthread_join(thread, NULL);
exit(0);
Your thread function should return a value since it is declared to do so. Returning NULL is fine.
I think you shoudl this code:
#include <thread>
#include <fstream>
using namespace std;
void write(string filename)
{
ofstream outfile(filename);
outfile<<"Hello World!"<<endl;
outfile.close();
}
int main()
{
thread t(write, "file.txt");
t.join();
}
use this command to compile the code:g++ -g -std=c++11 test.cpp -lpthread

Understanding pthread_detach

The following prints
In Main()
Hello World
Hello World
Why does this print Hello World twice? If I use pthread_join() the desired output occurs (only one Hello World preceeded by a In Main().
#include <pthread.h>
void *thread_func(void *arg);
int main(int argc, char **argv)
{
int s;
void *res;
pthread_t t1;
s = pthread_create(&t1, NULL, thread_func, "Hello World\n");
if (s != 0)
printf("Err\n");
printf("In Main()\n");
s = pthread_detach(t1);
if (s != 0)
printf("Err\n");
return 0;
}
void *thread_func(void *arg)
{
char *s = (char *)arg;
printf("%s", s);
pthread_exit(0);
}
I understand pthread_detach tells the library to release all of the resources utilized by the pthread once the thread is terminated... and since I terminate it at the end of thread_func, everything should be okay right?
What am I missing here?
In my opinion you are using a non-thread-safe version of the standard library (prints, fflush...). I have already seen this kind of (apparently) non-logical behavior on a old unix-like real time system. There were two different versions of std library, one for single-threaded mode and one for multithreaded. Of course, the default was single threaded...
In general, accesses to file pointers and similar things should be serialized with mutexes. In your program there are two thread terminations, each may want to call implicitly an fflush, but since the underlying buffers are not meant to be accessed concurrently, it may happen that both flushes write the same data to the output file descriptor.

Creating multiple threads and invoking other exectuables in Cygwin through system()?

I am working on a project in Cygwin. In an attempt to create multiple threads in C, and each thread calls another executable through the command line using the system() function, it turns out things are not working properly. Specifically, the code I have is like this:
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
system("date ");
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
But it does not work. The error I get is segmenetation fault with stack overflows. Anyway has an idea on how to call other executables in the system shell in parallel by creating multiple threads?
Thanks.
Add this code :
for(t=0; t<NUM_THREADS; t++){
pthread_join(threads[t], NULL);
}
before
pthread_exit(NULL);
as called in main().
Several bugs here:
In the main() function, after you create the thread, you should use pthread_exit() to exit from all the individual thread. So exit() use is not right here.
In the end of the main() function, just before you terminate the main thread, call pthread_join() to wait for all the individual thread to terminate.
At the end after all the child threads have terminated, you can call exit() to terminate the process itself.
http://www.thegeekstuff.com/2012/04/terminate-c-thread/
That issue looks worth reporting to the Cygwin mailing list.
What you can do instead is to do away with threads and use fork()/exec() or spawn(_P_NOWAITO, ...) to create the child processes.
(spawn() actually is a family of functions; see /usr/include/process.h for details. Its use is recommended as it avoids Cygwin's high fork overhead.)

Resources