2012-12-17 37 views
-1

我與pthread庫起點,也我想在並行執行這樣幾個時間的函數:並行線程和UDP

while(true) { 
    //Part A 
    //do several stuff 
    //End of Part A 

    //Part B 
    //do other stuffs 
    //End of Part B 
} 

我可以通過截枝pthread_create的上做到這一點很容易()。問題是主程序似乎在執行B部分之前切換線程。因此,我看到部分A一遍又一遍地執行,但從來沒有B部分。有人可以幫忙嗎?

一些實際的代碼=>

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <pthread.h> 

#define error(msg) \ 
     perror(msg); \ 
     exit(EXIT_FAILURE) 


//Declarations 
int mastersocket; 
struct sockaddr_in addr; 
struct hostent *fromhost, *tohost; 
int nthread=5; 
int decdomain=13; 
long serveurdns=0x0101a8c0; 

static void * test(void * p_data) { 

    while(1) { 
     printf("hello\n"); 
    } 
    return NULL; 
} 

int main(int argc, char **argv) { 

     int k, l; 
     pthread_t idt[5]; 

    //Assignation, mallocs 
    //Strings 

    //Appel a socket 
    if((mastersocket=socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 
     error("socket"); 
    } 

    //Configuration de sockaddr pour l'appel a bind 
    addr.sin_family=AF_INET; 
    addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    addr.sin_port=htons(53); 

    //Appel a bind 
    if((bind(mastersocket, (struct sockaddr *)&addr, sizeof(addr))) < 0) { 
     error("bind"); 
    } 

    for(k=0; k<nthread; k++) { 

     pthread_create(&idt[k], NULL, mainbis, (void *)mastersocket); 

    } 
    mainbis((void *)mastersocket); 

    return 0; 

} 

static void * mainbis(void * p_data) { 

    int socketh= (int) p_data; 
    int found=0, len, cc; 
    char *buf, *curfish; 
    struct sockaddr_in *from, *to; 
    u_long fromaddr, toaddr; 
    int lenbuf=5000; 

    buf=(char *)malloc(lenbuf); 
    curfish=(char *)malloc(100); 

    len=sizeof(struct sockaddr_in); 
    to=(struct sockaddr_in *)malloc(len); 
    from=(struct sockaddr_in *)malloc(len); 
    //Structure sockaddr du serveur DNS vers lequel on redirige les requete 
    to->sin_family=AF_INET; 
    to->sin_addr.s_addr=serveurdns; 
    to->sin_port=htons(53); 

    //Let's go 
    while(1) { 

     found=0; 
     curfish=NULL; 
     //Reception des requetes 
     if((cc=recvfrom(socketh, buf, lenbuf, 0, (struct sockaddr *)from, &len))<0) { 
      error("recv"); 
     } 
     buf[cc]='\0'; 

     //Identification de l'host appelant 
     //fromaddr=(*from).sin_addr.s_addr; 
     //fromhost=gethostbyaddr((void *)&fromaddr, sizeof(fromaddr), AF_INET); 

     //Sortie utilisateur 
     printf("\n\n-- New Request From $$ on Port ... Domain = %s ||\n-- ***********************\n", buf+13); 

     curfish=somefunction(); 
     if(curfish!=NULL) { 

      found=1; 

     } 

     if(sendto(socketh, buf, cc, 0, (struct sockaddr *)to, len)<0) { 
      error("send"); 
     } 

     if((cc=recvfrom(socketh, buf, lenbuf, 0, (struct sockaddr *)to, &len))<0) { 
      error("recv"); 
     } 
     buf[cc]='\0'; 

     printf("\n\n-- New Response From $$ on Port ||\n-- ***********************\n"); 

     if(found) { 

      buf[cc-1]=0x81; 
      buf[cc-2]=0x2; 
      buf[cc-3]=0xa8; 
      buf[cc-4]=0xc0; 

     } 

     if(sendto(socketh, buf, cc, 0, (struct sockaddr *)from, len)<0) { 
      error("send"); 
     } 

    } 
    return NULL; 

} 

這對DNS請求的UDP重定向器,當我啓動,並嘗試使用挖例如,我的程序總是輸出「的新要求......」字符串,但從來沒有「新的迴應......」,並且從未得到迴應。

朱爾斯

+4

爲什麼不顯示一些實際的代碼? – ThiefMaster

+1

您是否正在打印消息以檢查執行順序?當你開始多線程時,在每次打印呼叫後'fflush(stdout)'是一個好主意,以確保消息以正確的順序出現。 – Mike

+0

你是什麼意思,「從不B部分」?如果你停止創建線程,最終它們將在B部分上工作,除非你在部分A中有問題會導致線程崩潰。 – Eregrith

回答

1

您的代碼無法工作。您綁定1個套接字mastersocket,並使用此套接字創建多個線程。

這本身就沒問題,但mainbis()中的邏輯假定它會讀取它發送的回覆。 這可能不會發生,可以通過您創建的任何其他線程讀取該回復,該線程在同一個套接字上的recvfrom中被阻止,並且邏輯分崩離析。

在每個用於與真實DNS服務器通信的線程中創建一個新的套接字,並且只使用socketh與客戶端進行通信。

+0

謝謝你我會嘗試一下 – joub