C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 03-12-2009, 12:01 PM   #1
Registered User
 
Join Date: Nov 2007
Posts: 96
Multiple Threads

I am trying to create multiple threads in a client/server program but I am only able to run one thread at a time. Here is a copy of what I have thus far and I always open to suggestions and/or directions of what to look into

Code:
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include "http.h"
#include "myTCP.h"

void *runner( void * ptr);

struct parm{
	int socket;
	char path[100];
	char *from; 
	char *userAgent;
};

int thread_count=0; //Current amount of threads operating
int conditionMet=0; //Used as a flag to loop through until mutex is unlock

pthread_cond_t      cond  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t     mutex = PTHREAD_MUTEX_INITIALIZER;

int main(int argc, char *argv[]) {
	int	port=-999;		/* port number to connect to, on server */
	int	msock=-999;		/* socket descriptor for connection */
	int  iRet; //Return value for pthread_create
	int  pid; //process id
	int MAX_THREAD=-999; //Maximum amount of threads allowed to run

	char *server_full_message = "HTTP/1.0 502 Server temporarily overloaded\n\n502 SERVER TEMPORARILY OVERLOADED\n";
 
	struct parm *p;

//	p=(parm *)malloc(sizeof(parm)*n); //Use this when you have a thread pool
	p=(struct parm *)malloc(sizeof(struct parm)); //Allocate space for the p structure

	pid = getpid();
	if(argc==1) {
		p->userAgent = argv[0];
		port = WL_PORT;	
		MAX_THREAD = 5;
	} else if(argc==2) {
		p->userAgent = argv[0];
		MAX_THREAD = atoi(argv[1]);
		port = WL_PORT; 
	} else if (argc==3) {
		p->userAgent = argv[0];
		MAX_THREAD = atoi(argv[1]);
		if(atoi(argv[2]) >1024) port = atoi(argv[2]);
		else port = WL_PORT;
	} else {
		fprintf(stderr,"ERROR: useage:  <%s> <path> [<Max # Threads>] [<Port>]\n", argv[0]);
		exit(1);
	}
	#ifdef DEBUG
		fprintf(stderr,"DEBUG: %d %s will listen on port %d\n", pid, argv[0], port);
		fprintf(stderr,"DEBUG: MAX_THREAD = %d\n", MAX_THREAD);
	#endif

	pthread_t aThread[MAX_THREAD]; //Thread to be executed

      msock = myTCPserverSocket(port, argv[0]); 


	/* 
	* Now accept connections and service clients forever,
	* There is no "graceful" exit here.
	* messages consist of 1 to 255 bytes.
	*	the first byte msize = mess[0] is the size of the message,
	*		including the fisrt byte.
	*	the bytes mess[1]. mess[2]. ... mess[msize-1] comprise the data
	*		in the message.
	*/
	while(1) {
		/*Accept the client's socket*/
	      p->socket = myTCPaccept(msock, argv[0]);

		if(thread_count <= MAX_THREAD) {
			iRet = pthread_create(&aThread[thread_count], NULL, runner, (void *) p);
			thread_count++;
//			pthread_join(aThread, NULL);
		} 
		else { //The server is currently operating with the maximum number of threads
			fprintf(stdout, "Successfully Received Messsage From Client\n");

			//Respond to the Client notifying them that the server was too busy
			write(p->socket, server_full_message, strlen(server_full_message));

			fprintf(stdout, "Successfully Responded To Client\n");
			myTCPclose(p->socket);
		}
	}
}

void *runner( void *arg) {
	int sleepTime =0;
	int get_return=-999;	/*Return value for the myHTTPserverGet function*/
	int server_return=-999;	/*Return value for the myHTTPserverResponse function*/
	int rc;

	if( (rc = pthread_mutex_lock(&mutex)) != 0) {
		fprintf(stderr, "Error locking the mutex\n");
		fprintf(stderr, "ERRNO Value: %s\n", strerror(errno));
		exit(1);
	}

	struct parm *p = (void *) arg;
	
	//Get the client's request
	if((get_return = myHTTPserverGet(p->socket, p->path, p->from, p->userAgent, &sleepTime)) < 0) {
	     	fprintf(stdout, "Trouble in myHTTPserverGet.\nReturn Value = %d\n", get_return);
	      exit(1); 
	}

	sleep(sleepTime);			

	//Respond to the Client
	if((server_return =myHTTPserverResponse(p->socket, p->userAgent, get_return, p->path, sleepTime)) < 0) {
		fprintf(stdout, "Trouble in myHTTPserverResponse.\nReturn Value = %d\n", server_return);
		exit(1);
	}

	myTCPclose(p->socket);

	if( (rc = pthread_mutex_unlock(&mutex)) != 0) {
		fprintf(stderr, "Error locking the mutex\n");
		fprintf(stderr, "ERRNO Value: %s\n", strerror(errno));
		exit(1);
	}

	thread_count--;	
	pthread_exit(0);
}

Last edited by NuNn; 03-12-2009 at 01:54 PM.
NuNn is offline   Reply With Quote
Old 03-12-2009, 12:11 PM   #2
Registered User
 
Join Date: Nov 2007
Posts: 96
Okay, I have figured out that the pthread_join was causing the server to wait until one thread had finished. But now I am receiving erros when multiple threads are trying to connect. Shouldn't the mutex prevent this?
NuNn is offline   Reply With Quote
Old 03-12-2009, 01:55 PM   #3
Registered User
 
Join Date: Nov 2007
Posts: 96
I have updated my code to what I now have
NuNn is offline   Reply With Quote
Old 03-14-2009, 11:29 PM   #4
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,844
>> But now I am receiving errors when multiple threads are trying to connect. Shouldn't the mutex prevent this?
We don't know the "errors" so we can't tell you how to prevent them. Here's a quick code review of what you posted:

>> int MAX_THREAD
Reserve all caps for constants/#defines

>> char *server_full_message
Should be "const char *"

>> p=(struct parm *)malloc
No need to cast malloc in C

>> thread_count++
Unsynchronized access to the same memory location by multiple threads - undefined behavior.

Synchronization aside, your algorithm for using aThread and thread_count is flawed. Imagine you create thread 0 and thread 1 ... thread 0 finishes ... thread_count is now 1 and the next thread created will overwrite thread 1's entry in aThread.

>> pthread_mutex_lock(&mutex)
What's the point of having threads if none of the threads can actually run at the same time?

gg
Codeplug is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Need help with multiple threads Cogman Windows Programming 2 07-05-2009 09:40 AM
Multiple Threads, One listener. PING Networking/Device Communication 3 03-27-2009 12:19 PM
a point of threads to create multiple threads v3dant C Programming 3 10-06-2004 09:48 AM
Using multiple threads in REALLY old compilers scooby13q C++ Programming 2 12-16-2002 04:31 PM
More Winsock threads: Proper way to recv() and send() to multiple clients Unregistered Windows Programming 2 03-05-2002 05:52 AM


All times are GMT -6. The time now is 07:04 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22