PDA

View Full Version : pthreads, I created the thread, passed a function, function never runs.



mr_coffee
02-26-2009, 04:36 AM
Hi guys.

So basically my program is doing the following:
The parent: recver process is going to spawn 1 thread to read a file the child process is sending. The child process is writing a file to a message queue (IPC) and the parent process is spawning a thread and reading the message queue and will then also write the new file.
Before I tried to throw threads in this program, it was working fine with just 2 processes, 1 process writing to the message queue the other process reading and wrtiing a new file. So the message queue system isn't the issue it is the threading issue.



/* Functions */
int main( int argc, char **argv )
{
int pid;
int read_index = 0, write_index = 0, new_index = 0;
int err;
FILE *fp;

/* Check for arguments */
if ( argc < 3 )
{
/* Complain, explain, and exit */
fprintf( stderr, "missing or bad command line arguments\n" );
fprintf( stderr, CLIENT_USAGE );
exit( -1 );
}

/* get the index for the IPC object */
err = create_ipc( &read_index, &write_index );
if ( err ) {
fprintf( stderr, "create ipc error\n" );
exit(-1);
}

/* create receiver process */
if (( pid = fork() != 0 )) {
/* parent: recver */

/* setup the IPC channel */
err = setup_ipc_parent( read_index, write_index, &new_index );
if ( err ) {
fprintf( stderr, "rcver: error in ipc setup\n" );
exit(-1);
}



/* open the output file and return the file descriptor */
if (( fp = fopen( argv[2], "w+" )) < 0 ) {
fprintf( stderr, "rcver: file open failure\n" );
return -1;
}

/* create threads to receive the file contents */
run_pool_threads( fp, new_index, rcv_file );
//fclose( fp );

/* dump the file contents */
//rcv_file( argv[2], new_index );
fprintf( stderr, "rcver: finished\n" );
}
else {
/* childd */

/* setup the IPC channel */
err = setup_ipc_child( read_index, write_index, &new_index );
if ( err ) {
fprintf( stderr, "sender: error in ipc setup\n" );
exit(-1);
}



//added
/* open the input file and return the file descriptor */
if (( fp = fopen( argv[1], "r" )) < 0 ) {
fprintf( stderr, "sender: file open failure\n" );
return -1;
}


/* send the file contents */
//send_file( argv[1], new_index );
send_file(fp,new_index);

fprintf( stderr, "sender: finished\n" );
}

exit( 0 );
}


Here is the code that creates the thread, notice I'm using a structure becuase I need to pass in 2 parameters to the processes, a file descriptor and a file pointer.


int run_pool_threads( FILE *fp, int fd, void *(*threadfn)(void *))
{
/* build, run, and manage all the sorting threads -- run rcv_file for each */
//for now there will be only 1 thread.

pthread_t thread_id;


//We must create a structure to pass multiple arguments to the thread, such as fp and index
thread_work_t * work_t = malloc(sizeof(thread_work_t));
work_t->fp = fp;
work_t->fd = fd;

//creating the new thread and passing the thread_work_t structure
pthread_create( &thread_id, NULL, threadfn, work_t);



return 0;
}



Here is the function I'm passing to the thread, I don't beleive this ever gets ran because when I look at the output it never prints "Thread number: ". And the parent process just ends.



void *rcv_file( void *arg )
{
printf("Thread number %ld\n", pthread_self());
//you must cast the arg to the correct data type to access its data members
thread_work_t *work_t;
work_t = (struct thread_work *) arg;


//create a struct to hold the msg type and message
struct msgbuf_t msg;
int cmd = IPC_STAT;

int rtrn = msgctl(work_t->fd, cmd, &BUFF);
if (rtrn == -1)
{
perror("msgctl: msgctl failed");
return EXIT_FAILURE;
}

printf("msg_qnum: %d\n",BUFF.msg_qnum);



for(;;)
{

if(BUFF.msg_qnum == 0) //there is no messages to read! so wait.
{
sched_yield();
}

//if (msgrcv(index, &msg, MSGBUF_SIZE, 0, 0) == -1) {
if (msgrcv(work_t->fd, &msg, MSGBUF_SIZE, 0, 0) == -1) {
perror("msgrcv");
exit(1);
}


if(msg.type == MEND)
{
printf("Got MEND from sender, exit\n");
// fclose(fp);
fclose(work_t->fp);
break;
}
else if(msg.type == MTYPE)
{
printf("rev: %s", msg.text);
//fprintf(fp,"%s",msg.text);
fprintf(work_t->fp,"%s",msg.text);

}
else
{
printf("WE GOT SOMTHING ELSE! LOL\n");
}

}

return 0;




HEre is the output:


#
cory@ubuntu:~/Documents/Operating Systems/p2$ ./p2 test2/ltest ltestOUT
KEY generated: 1090584577
read and write id's: 32769
sent: 3 help me, mr wizard!
sent: 7 help me, mr wizard!
sent: 6 help me, mr dude!
sent: Found EOF
sender: finished
rcver: finished



As you can see its sending fine, but it never reads from the message queue, the thread I don't believe is ever getting ran and Im' not sure why.

ANy help would be great!

Codeplug
02-26-2009, 06:59 AM
Right after calling run_pool_threads(), exit() is called - bringing the down the process and all it's threads.

You need to to either join with the thread returned by pthread_create(), or create the thread detached, then call pthread_exit() instead of exit() in main().

gg

mr_coffee
02-26-2009, 11:48 PM
Thanks a lot Codeplug, worked!