이번에 리눅스 공부를 하고있는데 싱글클라이언트를 다중클라이언트로 바꾸는 작업을 해보고있는데 계속 막힙니다…
제가 수정한 소스코드인데 여기서 실행은 잘되는데 클라이언트 여러개에서 클라이언트1만 작동이되고 나머지는 아무 작동이 안됩니다… 제가 봤을때 pthread_create쪽을 잘못사용한것 같은데 한번 봐주세요 ㅠㅠ
ps 여기서 main함수에서 for문에서 Client_constructor함수로 호출하여서 쓰레드를 여러개 생성하는 구조인데 main함수하고 Client_constructor에서 잘못된점 찾아주시면 감사하겠습니다…
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "window.h"
#include "db.h"
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
struct ClientControl {
// encapsulation of code to control execution of client threads
pthread_mutex_t go_mutex;
pthread_cond_t go;
int stopped;
} clientcontrol = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
void ClientControl_wait() {
// called by client threads to wait until progress is permitted
pthread_mutex_lock(&clientcontrol.go_mutex);
while(clientcontrol.stopped)
pthread_cond_wait(&clientcontrol.go, &clientcontrol.go_mutex);
pthread_mutex_unlock(&clientcontrol.go_mutex);
}
void ClientControl_stop() {
// called by main thread to stop client threads
clientcontrol.stopped = 1;
}
void ClientControl_release() {
// called by main thread to resume client threads
pthread_mutex_lock(&clientcontrol.go_mutex);
clientcontrol.stopped = 0;
pthread_cond_broadcast(&clientcontrol.go);
pthread_mutex_unlock(&clientcontrol.go_mutex);
}
// the encapsulation of a client thread, i.e., the thread that handles
// commands from clients
typedef struct Client {
pthread_t thread;
window_t *win;
} Client_t;
void *RunClient(void *);
int handle_command(char *, char *, int len);
Client_t *Client_constructor(int ID) {
Client_t *new_Client = (Client_t *)malloc(sizeof(Client_t));
char title[16];
int a;
if (new_Client == 0)
return 0;
sprintf(title, "Client %d", ID);
new_Client->win = window_constructor(title);
// this constructor creates a window and sets up
// a communication channel with it
a = pthread_create(&(new_Client->thread), NULL, RunClient, (void*)new_Client);
pthread_detach(new_Client->thread);
if(a < 0){
perror("thread create errror!");
exit(0);
}
/*
else{
RunClient((void*)new_Client);
pthread_detach(new_Client->thread);
return new_Client;
}*/
return new_Client;
}
void Client_destructor(Client_t *client) {
window_destructor(client->win);
// the destructor removes the window
free(client);
}
// code executed by the client thread
void* RunClient(void *arg) {
Client_t *client = (Client_t *) arg;
// main loop of the client thread: fetch commands from window, interpret
// and handle them, return results to window.
char command[256];
char response[256] = {0}; // response must be null for the first call to serve
serve(client->win, response, command);
while(handle_command(command, response, sizeof(response))) {
serve(client->win, response, command);
}
Client_destructor(client);
return 0;
}
int handle_command(char *command, char *response, int len) {
ClientControl_wait();
if (command[0] == EOF) {
strncpy(response, "all done", len-1);
return(0);
} else {
interpret_command(command, response, len);
}
return(1);
}
int main(int argc, char *argv[]) {
char buf[256];
int ClientCount = 1;
Client_t *c;
if (argc != 1) {
fprintf(stderr, "Usage: server\n");
exit(1);
}
for(;ClientCount<3;){
if('\n' == *fgets(buf, 256, stdin)){
Client_constructor(ClientCount++);
}
}
//c = Client_constructor(0); //single client
//RunClient((void *)c); //single client run
//Client_destructor(c); //single client_destruct
//pthread_exit(0);
return(0);
}