Reputation: 696
I am trying to get two threads to communicate through a pipe in C++ on linux (Ubuntu, 12.04, 3.8.13). I just want to write a character from one thread to the pipe, and get the other thread to read it and display it.
I am using the clone() function to create threads. This is related to some homework, so I cannot use pthreads or something else.
The program:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <fstream>
#include <cmath>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
#include <fcntl.h>
using namespace std;
int p[2];//pipe
void read_pipe()
{
int c;
char charac[2];
read(p[0],charac,sizeof(charac));
//usleep(1000);
cerr<<"Read from pipe: "<<charac<<endl;
}
void write_pipe ()
{
write(p[1],"a",sizeof("a"));
cerr<<"Wrote to pipe: "<<"a"<<endl;
}
int thread1(void*)
{
close(p[0]);
write_pipe();
_exit(0);
}
int thread2(void*)
{
close (p[1]);
read_pipe();
_exit(0);
}
int main()
{
pipe(p);
char *stack_thread1=(char*)malloc(16384);
stack_thread1 +=16383;//stack grows downward -- gives seg fault otherwise
char *stack_thread2=(char*)malloc(16384);
stack_thread2 +=16383;//stack grows downward -- gives seg fault otherwise
int64_t elapsed_ns=0;
//create thread1
int tpid1=clone(thread1, (void*)stack_thread1, CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_VM, NULL);
cerr<<"\nThread1 created\n";
//create thread2
int tpid2=clone(thread2, (void*)stack_thread2, CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_VM, NULL);
cerr<<"\nThread2 created\n";
waitpid(tpid1,NULL,__WCLONE);//wait for clones to finish
waitpid(tpid2,NULL,__WCLONE);
usleep(5000);//make sure clones finished
cout<<"\nMain thread after sleep\n";
return 0;
}
Output is weird, different each time, for example:
Thread1 created
Thread2 created
Read from pipe:
Main thread after sleep
Sometimes it gives me the error: Illegal instruction. Running it in gdb also gives me illegal instruction.
Any ideas what's wrong?
Any help is appreciated!
Upvotes: 0
Views: 1456
Reputation: 44201
If you pass the CLONE_FILES
flag, you can't close your pipe files because both threads share the same set of file descriptors. Closing it from one thread will close it for the other thread as well.
Upvotes: 1