gpt4 book ai didi

c - Pthread 优先级和调度

转载 作者:太空宇宙 更新时间:2023-11-04 08:22:29 27 4
gpt4 key购买 nike

我正在尝试使用 Pthreads 来设置优先级和调度策略。

我修改了一个简单的套接字(可在线下载),带有一个服务器和几个客户端。这些客户端只是向服务器发送一个字符串。

服务器正在为每个连接的客户端创建一个新线程,并为每个新连接设置更高的优先级,这意味着最后一个连接的客户端是具有最高优先级的。我期望的结果是具有最高优先级的线程是打印出来的线程,直到该客户端连接,而其他线程应该等待。

但是,这不是我得到的结果。无论如何,线程都会被执行,即使是优先级较低的线程。我什至尝试了几种配置,例如使用 pthread_join,但在这种情况下,调度程序将等待该线程完成执行,如果调用另一个具有更高优先级的线程(在我的示例中另一个客户端连接),这是错误的,因为它应该将 CPU 释放给这个新创建的线程。

代码如下:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <sys/time.h>

#define PORTNUMBER 8888

int prioInit = 30; //global variable to initialize priority

struct serverParm
{
int connectionDesc;
};

//function used to increase priority to new threads
void addPrio(int *prio)
{
*prio = *prio + 10;
}

void *serverThread(void *parmPtr)
{
#define PARMPTR ((struct serverParm *) parmPtr)
int recievedMsgLen;
char messageBuf[1025];

struct sched_param Priority_Param; //struct to set priority
int policy=SCHED_FIFO; //kind of policy desired, either SCHED_FIFO or SCHED_RR, otherwise Linux uses SCHED_OTHER

// Server thread code to deal with message processing
printf("DEBUG: connection made, connectionDesc=%d\n",
PARMPTR->connectionDesc);

pthread_t self_id= pthread_self(); // I ask for the tid..
Priority_Param.sched_priority = prioInit; //.. set the priority (the higher the sooner it is executed, min at 1, max at 99)..
addPrio(&prioInit); //..increase the base priority..
if(pthread_setschedparam(self_id, policy, &Priority_Param) != 0) //.. and set the scheduling options.
{
printf("Error Set Sched\n");
perror("");
exit(1);
}

if (PARMPTR->connectionDesc < 0)
{
printf("Accept failed\n");
exit(1);
}

// Receive messages from sender
while ((recievedMsgLen=
read(PARMPTR->connectionDesc,messageBuf,sizeof(messageBuf)-1)) > 0)
{
recievedMsgLen[messageBuf] = '\0';
printf("Message: %s\n",messageBuf);
}
close(PARMPTR->connectionDesc); // Avoid descriptor leaks
free(PARMPTR); // And memory leaks
}

int main ()
{
int listenDesc;
struct sockaddr_in myAddr;
struct serverParm *parmPtr;
int connectionDesc;
pthread_t threadID;

// Create socket from which to read
if ((listenDesc = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("open error on socket");
exit(1);
}

// Create "name" of socket
myAddr.sin_family = AF_INET;
myAddr.sin_addr.s_addr = INADDR_ANY;
myAddr.sin_port = htons(PORTNUMBER);

if (bind(listenDesc, (struct sockaddr *) &myAddr, sizeof(myAddr)) < 0)
{
perror("bind error");
exit(1);
}

// Start accepting connections
listen(listenDesc,5);

while (1)
{
// Wait for a client connection
connectionDesc = accept(listenDesc, NULL, NULL);

// Create a thread to actually handle this client
parmPtr = (struct serverParm *)malloc(sizeof(struct serverParm));
parmPtr->connectionDesc = connectionDesc;
if (pthread_create(&threadID, NULL, serverThread, (void *)parmPtr)
!= 0)
{
perror("Thread create error");
close(connectionDesc);
close(listenDesc);
exit(1);
}

printf("Parent ready for another connection\n");
}

}

我正在使用 -pthread 选项进行编译并以 root 身份运行,以便设置和更改策略和优先级。我肯定在这里遗漏了一些东西,但我也想知道是否可以真正使用和更改调度选项,以便具有类似于实时的行为。

最佳答案

当必须在两个或多个可运行线程之间做出选择时,调度程序策略和优先级用于确定哪个线程将运行

如果您的高优先级线程阻塞在 read() 中,那么它就没有资格运行,而可运行的低优先级线程将有机会运行。优先级的意思是,即使所有可用的 CPU 核心都在运行低优先级线程,当数据从网络到达高优先级线程时,低优先级线程将立即被抢占,以便高优先级线程可以跑。

如果您想查看优先级的影响,让一个低优先级线程做大量工作,这样它几乎总是在使用 CPU:您的高优先级线程仍应立即响应网络输入。

(但是如果你这样做,要么对低优先级线程使用非实时优先级,要么确保你打开了一个以高实时优先级运行的 shell,这样低优先级线程就不会'在需要时阻止您的 shell 运行)。

旁注:您的 addPrio() 函数很活泼——它应该在对 *prio 的更改周围锁定一个互斥量。

关于c - Pthread 优先级和调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32839010/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com