只有一个线程执行所述函数

时间:2018-02-15 05:03:58

标签: c multithreading

我正在尝试构建客户端代理服务器应用程序。它必须是多线程的。以下是我的代码的客户端:

 int main(int argc, char* argv[])  
 {  
      //socket variables  

      printf("\nEnter proxy address:");  
      fgets(IP,sizeof("127.0.01\n")+1,stdin);  
      fputs(IP,stdout);  
      printf("\nEnter a port:");  
      fgets(port,sizeof("5000\n")+1,stdin);  
      fputs(port,stdout);  
      if((strcmp(IP,"127.0.0.1\n"))!=0 || (strcmp(port,"5000\n"))!=0)  
      {  
           printf("Invalida proxy settings. Try again...");  
      }  
      else  
      {  

          int threads=0;
          printf("Enter number of threads you want to generate :D");
          scanf("%d",&threads);
          pthread_t* thread_pool= (pthread_t *) 
            malloc(threads*sizeof(pthread_t));
          for(int i=0; i<threads; i++){
               pthread_t tid;
               thread_pool[i]= tid;
          }
          for(int i=0; i<threads;i++){
                 pthread_create(&thread_pool[i],NULL,execute,NULL);
                 pthread_join(thread_pool[i],NULL);


          }

          free(thread_pool);
          }  
          return 0;  
 } 


void *execute(){
      pthread_mutex_lock(&mutex);
      ex();
      pthread_mutex_unlock(&mutex);
} 

void ex(){


   // create a socket  
           if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
           {  
                printf("socket not created\n");  
           }  
           memset(&client_sd, 0, sizeof(client_sd));  
           // set socket variables  
           client_sd.sin_family = AF_INET;  
           client_sd.sin_port = htons(5000);  
           // assign any IP address to the client's socket  
           client_sd.sin_addr.s_addr = INADDR_ANY;   
           // connect to proxy server at mentioned port number  
           connect(sd, (struct sockaddr *)&client_sd, sizeof(client_sd));  
           //send and receive data contunuously  

            printf("Type here:");  
            scanf("%s",&buffer);


            write(sd, buffer, sizeof(buffer));  
            printf("\nServer response:\n\n");  
            read(sd, buffer, sizeof(buffer));  
            fputs(buffer, stdout); 

            if(send(sd,buffer,strlen(buffer),0) < strlen(buffer))
               {
                    perror("Send Error!!\n");
               }

           char *source;

           if( recv(sd,response,RESPONSE_RECV_LIMIT,0) == 0 )
            {
                    perror("Recv : ");

             }
           source = strstr(response,SOURCE_START_IDENTIFIER);

           if(source == NULL)
          {
               source = strstr(response,SOURCE_START_IDENTIFIER2);      
           }    
           printf("%s\n",source);
           printf("\n %d",sizeof(response));


           printf("\n");       

           close(sd);  







}

为了使其更容易理解,我发布了整个代码。我无法弄清问题所在。无论我创建多少个线程,只执行一个。 在此先感谢:)

修订: 在修改后的代码中,我创建了一个用于连接线程的单独循环。问题出在我要求用户输入的地方。两个线程都连接到服务器。只有一个要求用户输入。只有一个得到回应。其他人在途中受阻。

2 个答案:

答案 0 :(得分:1)

pthread_join等待线程退出,所以你要做的是:

  1. 创建主题1
  2. 等待主题1完成
  3. 创建主题2
  4. 等待主题2完成
  5. 创建主题3
  6. 等待主题3完成
  7. ...
  8. 所以显然一次只能运行一个线程。

    你应该做的是:

    1. 创建主题1
    2. 创建主题2
    3. 创建主题3
    4. ...
    5. 等待主题1完成
    6. 等待主题2完成
    7. 等待主题3完成
    8. ...

答案 1 :(得分:0)

您的代码存在一些严重问题。首先是以下部分。

void *execute(){
  pthread_mutex_lock(&mutex);
  ex();
  pthread_mutex_unlock(&mutex);
} 

您没有明智地使用互斥锁。锁用于保护代码的关键部分,并且锁定一个完整的函数并不是一个好主意。

有两个主要原因?

1&gt; 线程具有独立的调用堆栈,因此不是在完整函数周围放置锁,而是一个好主意是确定所有线程将访问哪些公共资源或关键代码段用锁来保护它。

2&gt; 如果您正在锁定某个功能;然后在函数返回之前不会释放锁。如果您在从函数返回后解锁互斥锁然后创建下一个线程,那么您实际上并没有实现并行性,因为一次只有一个工作线程。

您的代码的另一个问题是使用以下部分,这是多余的,不会做任何事情。

      for(int i=0; i<threads; i++){
           pthread_t tid;
           thread_pool[i]= tid;
      }

最后正如其他评论中提到的那样,pthread_join是阻塞的 - 因此在等待当前关闭时不会创建新的线程。

/******YOUR CODE******/
      for(int i=0; i<threads;i++){
             pthread_create(&thread_pool[i],NULL,execute,NULL);
             pthread_join(thread_pool[i],NULL);
      }

这应该是

      for(int i=0; i<threads;i++){
             pthread_create(&thread_pool[i],NULL,execute,NULL);
      }
      for(int i=0; i<threads;i++){
             pthread_join(thread_pool[i],NULL);
      }