我正在研究一个多线程服务器应用程序。服务器接受来自多个设备的连接,并为每个连接分配一个线程。线程是一个循环线程,即它使用while循环,迭代直到客户端关闭连接。 / p>
目前,当多个客户端连接到服务器时,只有单个客户端能够进行通信,即单个设备发送的数据在服务器端接收并在数据库中更新,其他设备仍然连接到服务器,但没有从他们。对我来说似乎是什么原因(不确定只是假设)是只有一个线程仍在执行而其他线程没有轮到执行。
所以我想循环安排线程,以便每个线程都执行。如何循环调度线程
我在线获得了以下代码,但无法以循环方式安排线程。
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
这是我创建线程的代码:
connfd = accept(sock_desc, (struct sockaddr *)&echoClntAddr,(socklen_t*)&clntSock);
if(connfd > 0){
conn_desc = connfd;
puts("Connection accepted");
if(pthread_create( &thr, &attr , connection_handler , (void*)&conn_desc) < 0){
perror("could not create thread");
}
答案 0 :(得分:3)
您的问题 与调度程序策略无关。您的代码中存在潜在的竞争条件。
// parent thread
while (1) {
listen(...);
connfd = accept(sock_desc, (struct sockaddr *)&echoClntAddr,
(socklen_t*) &clntSock);
conn_desc = connfd;
pthread_create(&thr,&attr,connection_handler,(void*) &conn_desc);
}
// child thread function
void *
connection_handler(void *ptr)
{
int fildes = *(int *) ptr;
...
return (void *) 0;
}
竞争是父级可以在第一个线程能够取消引用ptr
之前触发第二个线程。因此,两个线程将使用相同的值connfd
。
为了纠正这个问题,我们需要稍微修改一下调用序列为pass-by-value:
// parent thread
while (1) {
listen(...);
connfd = accept(sock_desc, (struct sockaddr *)&echoClntAddr,
(socklen_t*) &clntSock);
pthread_create(&thr,&attr,connection_handler,(void*) connfd);
}
// child thread function
void *
connection_handler(void *ptr)
{
int fildes = (int) ptr;
...
return (void *) 0;
}
旁注:保证以这种方式在指针内传递int
,但对于粘贴者,请参见下文。
// parent thread
while (1) {
listen(...);
connfd = accept(sock_desc, (struct sockaddr *)&echoClntAddr,
(socklen_t*) &clntSock);
ptr = malloc(sizeof(int));
*ptr = connfd;
pthread_create(&thr,&attr,connection_handler,(void*) ptr);
}
// child thread function
void *
connection_handler(void *ptr)
{
int fildes = *(int *) ptr;
free(ptr);
...
return (void *) 0;
}