gpt4 book ai didi

c++ - linux CFS schedualar下C/C++多线程场景出现意外结果

转载 作者:太空宇宙 更新时间:2023-11-04 04:02:36 25 4
gpt4 key购买 nike

我在主线程内创建了多个线程(4个线程)。虽然每个线程执行相同的功能,线程的调度与预期的不一样。根据我对操作系统的理解,linux CFS 调度程序将分配“t”虚拟运行时间量,并且在该时间量到期时,CPU 被当前线程抢占,分配给下一个线程。通过这种方式,每个线程都将获得公平的 CPU 份额。我得到的并不符合预期。

我期望所有线程(线程 1-4、主线程)都会在同一线程(任何)下次获得 CPU 之前获得 CPU。

预期输出为

foo3-->1--->Time Now : 00:17:45.346225000

foo3-->1--->Time Now : 00:17:45.348818000

foo4-->1--->Time Now : 00:17:45.350216000

foo4-->1--->Time Now : 00:17:45.352800000

main is running ---> 1--->Time Now : 00:17:45.355803000

main is running ---> 1--->Time Now : 00:17:45.360606000

foo2-->1--->Time Now : 00:17:45.345305000

foo2-->1--->Time Now : 00:17:45.361666000

foo1-->1--->Time Now : 00:17:45.354203000

foo1-->1--->Time Now : 00:17:45.362696000

foo1-->2--->Time Now : 00:17:45.362716000 // foo1 thread got CPU 2nd time as expected

foo1-->2--->Time Now : 00:17:45.365306000

但是我得到

foo3-->1--->Time Now : 00:17:45.346225000

foo3-->1--->Time Now : 00:17:45.348818000

foo4-->1--->Time Now : 00:17:45.350216000

foo4-->1--->Time Now : 00:17:45.352800000

main is running ---> 1--->Time Now : 00:17:45.355803000

main is running ---> 1--->Time Now : 00:17:45.360606000

foo3-->2--->Time Now : 00:17:45.345305000 // // foo3 thread got CPU 2nd time UNEXPECTEDLY before scheduling other threads as per CFS

foo3-->2--->Time Now : 00:17:45.361666000

foo1-->1--->Time Now : 00:17:45.354203000

foo1-->1--->Time Now : 00:17:45.362696000

foo1-->2--->现在时间:00:17:45.362716000

foo1-->2--->现在时间:00:17:45.365306000

这是我的程序(thread_multi.cpp)

#include <pthread.h>
#include <stdio.h>
#include "boost/date_time/posix_time/posix_time.hpp"
#include <iostream>
#include <cstdlib>
#include <fstream>
#define NUM_THREADS 4

using namespace std;

std::string now_str()
{
// Get current time from the clock, using microseconds resolution
const boost::posix_time::ptime now =
boost::posix_time::microsec_clock::local_time();

// Get the time offset in current day
const boost::posix_time::time_duration td = now.time_of_day();
const long hours = td.hours();
const long minutes = td.minutes();
const long seconds = td.seconds();


const long nanoseconds = td.total_nanoseconds() - ((hours * 3600 + minutes * 60 + seconds) * 1000000000);
char buf[40];

sprintf(buf, "Time Now : %02ld:%02ld:%02ld.%03ld", hours, minutes, seconds, nanoseconds);
return buf;
}


/* This is our thread function. It is like main(), but for a thread*/
void *threadFunc(void *arg)
{
char *str;
int i = 0;

str=(char*)arg;

while(i < 100 )
{

++i;
ofstream myfile ("example.txt", ios::out | ios::app | ios::binary);

if (myfile.is_open())
{
myfile << str <<"-->"<<i<<"--->" <<now_str() <<" \n";

}
else cout << "Unable to open file";
// generate delay
for(volatile int k=0;k<1000000;k++);



if (myfile.is_open())
{
myfile << str <<"-->"<<i<<"--->" <<now_str() <<"\n\n";
myfile.close();
}
else cout << "Unable to open file";
}


}

int main(void)
{
pthread_t pth[NUM_THREADS]; // this is our thread identifier
int i = 0;

pthread_create(&pth[0],NULL, threadFunc, (void *) "foo1");
pthread_create(&pth[1],NULL, threadFunc, (void *) "foo2");
pthread_create(&pth[2],NULL, threadFunc, (void *) "foo3");
pthread_create(&pth[3],NULL, threadFunc, (void *) "foo4");



std::cout <<".............\n" <<now_str() << '\n';

while(i < 100)
{

for(int k=0;k<1000000;k++);

ofstream myfile ("example.txt", ios::out | ios::app | ios::binary);
if (myfile.is_open())
{
myfile << "main is running ---> "<< i <<"--->"<<now_str() <<'\n';
myfile.close();
}
else cout << "Unable to open file";


++i;
}

// printf("main waiting for thread to terminate...\n");
for(int k=0;k<4;k++)
pthread_join(pth[k],NULL);

std::cout <<".............\n" <<now_str() << '\n';
return 0;
}

这是完全公平的调度程序详细信息

kernel.sched_min_granularity_ns = 100000 kernel.sched_wakeup_granularity_ns = 25000 kernel.sched_latency_ns = 1000000

根据 sched_min_capsularity_ns 值,任何任务都将在该最短时间内执行,如果任务需要超过该最短时间,则计算时间片,并且每个任务都将在该时间片内执行。

这里时间片的计算使用公式,

time slice = ( weight of each task / total weight of all tasks under that CFS run-queue ) x sched_latency_ns

谁能解释一下为什么我会得到这些调度结果???任何有助于理解输出的帮助都将受到高度赞赏。预先感谢您。

我在linux下使用gcc。

编辑1:

如果我改变这个循环

for(int k=0;k<100000;k++);

进入

for(int k=0;k<10000;k++);

然后有时线程1连续10次获得CPU,线程2连续5次获得CPU,线程3连续5次获得CPU,主线程连续2次获得CPU,线程4连续7次获得CPU。看起来不同的线程在随机时间被抢占。

关于这些随机的连续 CPU 分配给不同线程的次数有什么线索吗??

最佳答案

CPU分配一些时间来执行每个线程。为什么每个线程的打印数量不同?

我将在一个例子中解释这一点:

承认你的计算机可以在 ns 内发出 100 条指令 承认打印 1 次相当于使用 25 条指令 承认每个线程有1ns的工作时间

现在您必须了解计算机中的所有程序都在消耗 100 条可用指令

如果当你的线程想要打印一些东西时,有 100 条可用指令,它可以打印 4 个句子。 如果当你的线程想要打印一些东西时,有 40 条可用指令,它可以打印 1 个句子。由于其他程序正在使用指令,因此只有 40 条指令。

你明白了吗?

如果您有任何疑问,欢迎您。 :)

关于c++ - linux CFS schedualar下C/C++多线程场景出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22488853/

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