2017-06-13 13 views
0

私はスレッドプールをテストするための簡単なコードを書いています。私は別のポートを介してサーバーにデータのsendin行をクライアントがあります。 一部のスレッドはデータを受信し、処理のために他のスレッドに送信します。 今のところ、私がやっている処理はファイルにデータを書き込むことだけです。Cプログラムはデバッグ時にファイルに書き込むだけです

ここにワーカースレッドのコードを示します。

void* worker_thread(void* arg){ 
    int i, workerNum; 
    pthread_t worker_id = pthread_self(); 
    char *ticket = (char*) arg; 
    char dumpfile[50]; 
    for(i=0;i<10;i++) 
     if(pthread_equal(worker_id, id_pool[i])) 
     break; 
    if(10==i){ 
     pthread_exit(NULL); 
    } 
    workerNum = i; 
    fprintf(stdout, "Worker [%d] busy\n",workerNum); 
    sprintf(dumpfile, "worker_%d.log",workerNum); 
    if(strlen(ticket)<4){ 
     fprintf(stdout, "Worker [%d] RELEASED!!\n",workerNum);  
     poolStatus[workerNum] = 0; 
     pthread_mutex_unlock(&mutexes[workerNum]); 
     pthread_exit(NULL); 
    } 
    FILE *logFile = fopen(dumpfile, "a+"); 
    // ticket[strlen(ticket)] 
    fprintf(logFile, "%s\n", ticket); 
    fclose(logFile); 
    sleep(workerNum+2); 
    poolStatus[workerNum] = 0; 
    fprintf(stdout, "Worker [%d] RELEASED!!\n",workerNum); 
    pthread_mutex_unlock(&mutexes[workerNum]); 
    pthread_exit(NULL); 
} 

コードは、デバッガ(GDB、linux)を実行すると動作します。私は単にコマンドラインでそれを実行すると、実行されますが、ファイルを作成しません! 助けてもらえますか?

完全なコード:

#include <time.h> 
#include <errno.h> 
#include <netdb.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <strings.h> 
#include <sys/time.h> 
#include <arpa/inet.h> 
#include <sys/ioctl.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 

#define BUFSIZE  65535 
#define NUMWORKERS 10 

static pthread_mutex_t mutexes[NUMWORKERS]; 
pthread_t id_pool[NUMWORKERS], id_servers[6]; 
int serverports[6]   = {22191, 22192, 22193, 7525, 7526, 7527}; 
char poolStatus[NUMWORKERS] = {0}; 

void error(char *msg) { 
    FILE *logFile = fopen("errorlog.log", "a+"); 
    fprintf(logFile, "%s\n", msg); 
    fclose(logFile); 
    exit(1); 
} 

void* serverListener(void* arg); 
void* worker_thread(void* arg); 


int main(){ 
    int i, t_err[6]; 
    for(i=0; i< NUMWORKERS; i++) 
     pthread_mutex_init(&mutexes[i],NULL); 
    for(i=0; i<6; i++){ 
     t_err[i] = pthread_create(&id_servers[i], NULL, serverListener, NULL); 
    } 
    pthread_join(id_servers[5], NULL); 
    return 0; 
} 


void* serverListener(void* arg){ 
    int    parentfd, childfd;  // parent socket & child socket 
    int    portno, clientlen;  // port number and size of client address 
    struct sockaddr_in serveraddr; 
    struct sockaddr_in clientaddr;// server and client addresses 
    struct hostent  *hostp;    // client host info 
    char    buf[BUFSIZE];   // message buffer 
    char    *hostaddrp;   // dotted decimal host addr string 
    int    optval, n;    // flag value for setsockopt and message byte size 
    unsigned int  CLOCKREF, CLOCKCOUNT; 
    pthread_t   id = pthread_self(); // own thread id 
    int    threadNumber, i=0;  // thread number linked to ort to listen to. 
    char    dumpfile[50]; 
    for(i=0; i<6; i++) if(pthread_equal(id, id_servers[i])) break; 
    threadNumber = i; 

    portno = serverports[threadNumber]; 
    sprintf(dumpfile, "receiver_%d.log",portno); 
    // socket: create the parent socket 
    parentfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (parentfd < 0) 
     error("ERROR opening socket"); 

    optval = 1; 
    setsockopt(parentfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)); 

    // build the server's Internet address 
    bzero((char *) &serveraddr, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 

    // let the system figure out our IP address 
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    // this is the port we will listen on 
    serveraddr.sin_port = htons((unsigned short)portno); 

    // bind: associate the parent socket with a port 
    if (bind(parentfd, (struct sockaddr *) &serveraddr, 
     sizeof(serveraddr)) < 0) 
     error("ERROR on binding"); 

    // listen: make this socket ready to accept connection requests 
    if (listen(parentfd, 5) < 0) /* allow 5 requests to queue up */ 
     error("ERROR on listen"); 

    // main loop: wait for a connection request 
    clientlen = sizeof(clientaddr); 
    while (1) { 
     // accept: wait for a connection request 
     childfd = accept(parentfd, (struct sockaddr *) &clientaddr, &clientlen); 
     if (childfd < 0) 
     error("ERROR on accept"); 

     // gethostbyaddr: determine who sent the message 
     hostp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, 
       sizeof(clientaddr.sin_addr.s_addr), AF_INET); 
     if (hostp == NULL) 
     error("ERROR on gethostbyaddr"); 
     hostaddrp = inet_ntoa(clientaddr.sin_addr); 
     if (hostaddrp == NULL) 
     error("ERROR on inet_ntoa\n"); 
     fprintf(stdout, "server established connection with %s (%s)\n", hostp->h_name, hostaddrp); 

     // read: read input string from the client 
     CLOCKREF = (unsigned int)time(NULL); 
     int counter = 0; 
     while(1){ 
      CLOCKCOUNT = (unsigned int)time(NULL) - CLOCKREF; 
      bzero(buf, BUFSIZE); 
      n = read(childfd, buf, BUFSIZE); 
      if (n < 0)  error("ERROR reading from socket"); 
      if(0==n) counter++; 
      if(3<=counter) { 
       close(childfd); 
       return; 
      } 

      int busyWorker = 1; 
      i = 0; 
      while(busyWorker){ 
       if(i>=NUMWORKERS) i = 0; 

       if(pthread_mutex_trylock(&mutexes[i])==0){ // not locked, can be used 
        fprintf(stdout, "port [%d] sends to thread [%d]\n", portno, i); 
        pthread_create(&id_pool[i], NULL, worker_thread, (void*)buf); 
        busyWorker = 0; 
        break; 
       } 
       i++; 
      } 
     } 
     close(childfd); 
    } 
} 

void* worker_thread(void* arg){ 
    int i, workerNum; 
    pthread_t worker_id = pthread_self(); 
    char *ticket = (char*) arg; 
    char dumpfile[50]; 
    for(i=0;i<10;i++) 
     if(pthread_equal(worker_id, id_pool[i])) 
     break; 
    if(10==i){ 
     pthread_exit(NULL); 
    } 
    workerNum = i; 
    fprintf(stdout, "Worker [%d] busy\n",workerNum); 
    sprintf(dumpfile, "worker_%d.log",workerNum); 
    if(strlen(ticket)<4){ 
     fprintf(stdout, "Worker [%d] RELEASED!!\n",workerNum);  
     poolStatus[workerNum] = 0; 
     pthread_mutex_unlock(&mutexes[workerNum]); 
     pthread_exit(NULL); 
    } 
    FILE *logFile = fopen(dumpfile, "a+"); 
    // ticket[strlen(ticket)] 
    fprintf(logFile, "%s\n", ticket); 
    fclose(logFile); 
    sleep(workerNum+2); 
    poolStatus[workerNum] = 0; 
    fprintf(stdout, "Worker [%d] RELEASED!!\n",workerNum); 
    pthread_mutex_unlock(&mutexes[workerNum]); 
    pthread_exit(NULL); 
} 
+0

stdoutに "Worker [%d] busy \ n"が表示されますか? –

+0

はい! stdoutに送られたすべてのメッセージがうまく印刷されます – PhoenixBlue

+0

'worker_thread'をどう呼びますか?あなたの質問には、問題が何であるかを示すコードがたくさんあります。 –

答えて

0

は、私は問題を発見したと信じて!

serverListenerスレッドからworker_threadにメッセージを渡すには、ソケットから読み取るためのバッファーへのポインターを使用しました。問題は、worker_threadが処理できるようになる前に、serverListenerは値をゼロ(bzero(buf, BUFSIZE))にリセットしました。 worker_threadは、サイズが4より大きい場合にのみファイルに書き込む必要があるという事実を考慮して、書き込みません。で

pthread_create(&id_pool[i], NULL, worker_thread, (void*)buf); 

: はので、私の問題を解決するために、私はラインを交換し

char *msg2send = strdup(buf); 
pthread_create(&id_pool[i], NULL, worker_thread, (void*)msg2send); 

そして、それはトリックをやりました! まだデバッグモードでファイルを作成する理由を説明していません...

関連する問題