Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的队列套接字连接_C_Multithreading_Sockets - Fatal编程技术网

C语言中的队列套接字连接

C语言中的队列套接字连接,c,multithreading,sockets,C,Multithreading,Sockets,在客户机-服务器体系结构中,我有一个接受客户机连接的服务器。我希望服务器同时接受3个连接,其余的连接(如果可用)将被挂起,以FIFO方式提供服务。 这样做的正确方式是什么 我想到的一个可能的方法是 制作一个计数器并检查其是否小于3,接受,在新线程中为客户机提供服务,并递增计数器。当计数器大于3时,只需接受套接字描述符并将其保存在队列中。当一个客户机完成他的工作时,停止线程(例如通过连接)和减量计数器,以允许另一个客户机得到服务。如果队列不是空的,请弹出一个套接字描述符,创建一个线程并为客户端提供

在客户机-服务器体系结构中,我有一个接受客户机连接的服务器。我希望服务器同时接受3个连接,其余的连接(如果可用)将被挂起,以FIFO方式提供服务。 这样做的正确方式是什么

我想到的一个可能的方法是

制作一个计数器并检查其是否小于3,接受,在新线程中为客户机提供服务,并递增计数器。当计数器大于3时,只需接受套接字描述符并将其保存在队列中。当一个客户机完成他的工作时,停止线程(例如通过连接)和减量计数器,以允许另一个客户机得到服务。如果队列不是空的,请弹出一个套接字描述符,创建一个线程并为客户端提供服务


非常感谢您的反馈

由于
listen
函数有一个可设置的待办事项,即它将保留队列中的所有连接,并且当调用
accept
时,队列中等待的第一个元素实际上被接受,因此这方面的解决方案如下所示

在无限循环中,只要计数器小于特定数目(同时服务的最大客户端数),就只接受连接。 声明一个
互斥锁
,该互斥锁保护每次接受连接时递增的计数器。 向b声明一个条件变量,用于在线程完成任务时发出信号。 使用该条件变量和互斥锁,若计数器大于X,则等待。 当服务于客户机的线程完成其任务时,减量计数器并发出条件信号。因此,无限循环将再次循环,并接受一个已经处于等待状态的客户机

这方面的一种可能实施方式是:

// global variable 
pthread_mutex_t lock;
pthread_cond_t cv;
int number_of_connected_client = 0;

// a function executed by a thread to handle each user
void *client_thread(void *arg) {

  /* some code */

  // thread is about to finish and return
  // client disconnected --> decrement number of connected clients 
  // signal that a client disconnected
  pthread_mutex_lock(&lock);
  number_of_connected_client-- ;
  pthread_cond_signal(&cv);
  pthread_mutex_unlock(&lock);
  return 0;
}

// infinte loop for accepting connections
while (1) {

  // serve 2 users at a time, queue the rest of the clients in the listen's queue 
  if( number_of_connected_client >= 2 ) {
    pthread_mutex_lock(&lock);      
    pthread_cond_wait(&cv, &lock);
    pthread_mutex_unlock(&lock);
  }

  connfd = accept(listenfd, (struct sockaddr *) NULL, NULL );

  // create a thread and serve the client 
  if( pthread_create( &thread_id , NULL , client_thread, (void*)connfd) <0)
    {
     // error in creating thread
     // do something 
    }

  // client is served --> increment number of connected clients 
  else {
    pthread_mutex_lock(&lock);
    number_of_connected_client ++;
    pthread_mutex_unlock(&lock);
  }

}
//全局变量
pthread_mutex_t lock;
pthread_cond_t cv;
连接的客户端的整数=0;
//由线程执行的处理每个用户的函数
void*客户端线程(void*arg){
/*一些代码*/
//线程即将完成并返回
//客户端断开-->减少已连接客户端的数量
//表示客户端已断开连接
pthread_mutex_lock(&lock);
连接的客户端的数目--;
pthread_cond_信号(&cv);
pthread_mutex_unlock(&lock);
返回0;
}
//用于接受连接的infinte循环
而(1){
//一次服务2个用户,将侦听队列中的其余客户端排队
if(连接的客户端数量>=2){
pthread_mutex_lock(&lock);
pthread_cond_wait(&cv,&lock);
pthread_mutex_unlock(&lock);
}
connfd=accept(listenfd,(struct sockaddr*)NULL,NULL);
//创建一个线程并为客户端提供服务
if(pthread_create(&thread_id,NULL,client_thread,(void*)connfd)增加连接的客户端数
否则{
pthread_mutex_lock(&lock);
连接的客户端++的数量;
pthread_mutex_unlock(&lock);
}
}

这只是一个简单的解决方法,可以让私有测试或硬件等工作正常进行。正确的处理方法是使用池线程,按照Inspired的评论分配任务。

或者您可能希望有3个工作线程,每个线程读取队列中的连接请求。(一般来说,从客户的角度来看,接受连接然后保持连接状态可能不是最好的体验。)你的意思是我将所有连接保持在一个队列中,并且有3个工作线程不断弹出和服务?哦,是的,我同意你的观点,但这只是为了练习。正确。这只是你建议的方案的简化(不再创建/加入线程,也不需要计数器)。为什么你会故意以这种方式限制服务器的可用性?我理解为什么不需要计数器,但是,创建线程呢?为什么不再需要?当线程完成任务并且客户端断开连接时,我不应该创建一个新线程而不是它吗?