- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在主线程内创建了多个线程(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/
我是一名优秀的程序员,十分优秀!