Thread: fork() problem

  1. #1
    Unregistered
    Guest

    fork() problem

    Hi,
    With the following code I'm trying to synchronize two functions, one that receives and one that sends messages (It's for a chat program). I run them both as pthreads

    Code:
    	if( pthread_create( &sendmsg, NULL, &sendmessage, ( void* )NULL ) != 0||
    	pthread_create( &recvmsg, NULL, &receivemessage, ( void* )NULL ) != 0 ){
    		puts( strerror( errno ) );
    		return 1;
    	}	
    	clearscreen();
    	move( DOWN, 23 );
    	pthread_join( recvmsg, NULL );
    	pthread_join( sendmsg, NULL );
    And it works good so far If I don't care about the cursor and just display arriving messages (so it would cut the line you're typing).
    But now i'm trying to move the cursor on the top, display the message, and jump back to where the user was typing. To do this, I have to save the input's byte offset and interrupt the current getch() call, which I'm fork()'ing off, from the parent process- so that I can have the other function move the cursor up, print the text, and move back. This is where my problem comes into play; I set a "received" flag when I received a message (heh) or when nothing has been received, but the typed line is finished and has to be sent. Problem: "received" only seems to be changed if the receivemessage() function writes to it. The parent doesn't recognise any change when the child writes to "received". I've tried using a pointer, but it makes no difference.

    Code:
    void *sendmessage( void *dummy )
    {
    	char buf[256],
    		buf2[256],
    		*temp;
    	int chr,
    		*chrptr = &chr,
    		i = 0;
    	pid_t process;
    	*chrptr = 0;
    	for( ;; )
    	{
    		while( *chrptr != 13){
    			printf( "%d\n", byteoffset );
    			*chrptr = 0;
    			switch( ( process = fork() ) ){
    				case -1: continue;
    				case 0:
    					while( byteoffset < 256 ){
    						*chrptr = getch();
    						if( *chrptr == 13 ){
    							buf[byteoffset] = 0;
    							for( i =0;
    							i < byteoffset;
    							i++ )
    							printf( "\b \b\r" );
    							break;
    						}
    						else{
    							printf( "%c",chr );
                                buf[byteoffset]=*chrptr;
                            }
    						++byteoffset;
    					}
    					printf( "chrptr = %d\n", *chrptr );
    					byteoffset = 0;
    					*rec = 1; /*!!!!*/
    					printf( "CHILD, received = %d\n", received);
    					usleep( 200000 );
    					exit( process );
    					break;
    				default:
    					*rec = 0;
    					while( received == 0 )
    						usleep( 200000 ),
    						printf( "%d\n", received ); /* stays 0 when child
    changes it*/
    					printf( "KILLING" );
    					kill( process , 0 );
    			}
    		}
    		*rec = 0;
    		puts( "loop over" );
    		usleep( 10 );
    		snprintf( buf2, 256, "<%s> %s", nick, buf );
    		if( strncmp( buf, "/exit", 5 ) == 0 ){
    			send( s2, "/exit", 6, 0 );
    			done_flag = 1;
    			close( s2 ), close( s );
    			exit( 0 );
    			break;
    		}
    		else send( s2, buf2, 256, 0 );
    	}	
    	return NULL;	 
    }
    
    void *receivemessage( void *dummy ){
    	int i;
    	char buf[256],
    		*temp;
    	for( ; done_flag == 0 ; ){
    		recv( s2, buf, 256, 0 );
    		received = 1;
    		putchar( '\r' );
    		if( strncmp( buf, "/exit", 5 ) == 0 ){
    			if( done_flag == 0 )
    				puts( "Other side has closed the connection" ), 
    				done_flag = 1;
    				return NULL;
    		}
    		else{
    			if( offset == 22 ){
    				clearscreen();
    				puts( buf );
    				for( i = 0; i < 23; i++ )
    					putchar( '\n' );
    			}
    			else{
    				 move( UP, 24 - offset );
    				puts( buf );
    				++offset;
    				for( int i = 0; i < 24 - offset; i++)
    					putchar( '\n' );
    			}
    			putchar( '\r' );
    			move( RIGHT, byteoffset );
    		}
    	}
    	return NULL;
    }
    Oh by the way, don't care about move() and getch()- those are functions from my "conio.h-port".
    Any help greatly appreciated.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Because when you do a fork(), the parent and child get separate copies of the data - modifications to one do not affect the other.

    pthreads do share the same data space, so you should be able to share data between them

  3. #3
    Unregistered
    Guest
    Hey Salem,
    first thanks for your reply. Does that mean I have to do this internal synchronization with pthreads, too? Isn't there any way the child can tell the parent when it's done? I think I can't use the *wait*() functions, because they would destroy the ``realtime'' synchronization again.
    No chance to share one variable somehow?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The way you have it written at present, the need for some synchronisation seems necessary

    Personally, I'd make the display update a separate thread (which can be a write only interface), which has an input message consisting of position and text.

    Your other two tasks can then send messages to your display task without worrying what the other is up to.

    I think...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  2. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  3. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  4. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  5. Replies: 5
    Last Post: 11-07-2005, 11:34 PM