【发布时间】:2014-03-18 19:12:31
【问题描述】:
我在主线程中创建了多个线程(4 个线程)。虽然每个线程都执行相同的功能, 线程的调度与预期的不同。根据我对操作系统的理解,linux CFS 调度程序将 分配“t”虚拟运行时间量,并且在该时间量到期时,CPU被当前线程抢占,并且 分配给下一个线程。通过这种方式,每个线程都将获得公平的 CPU 份额。我得到的不是预期的。
我预计所有线程(线程 1-4,主线程)将在下一次相同线程(任何)获得 CPU 之前获得 CPU。
预期输出是
foo3-->1--->现在时间:00:17:45.346225000
foo3-->1--->现在时间:00:17:45.348818000
foo4-->1--->现在时间:00:17:45.350216000
foo4-->1--->现在时间:00:17:45.352800000
main 正在运行 ---> 1--->现在时间:00:17:45.355803000
main 正在运行 ---> 1--->现在时间:00:17:45.360606000
foo2-->1--->现在时间:00:17:45.345305000
foo2-->1--->现在时间:00:17:45.361666000
foo1-->1--->现在时间:00:17:45.354203000
foo1-->1--->现在时间:00:17:45.362696000
foo1-->2--->Time Now : 00:17:45.362716000 // foo1 线程按预期第二次获得 CPU
foo1-->2--->现在时间:00:17:45.365306000
但我得到了
foo3-->1--->现在时间:00:17:45.346225000
foo3-->1--->现在时间:00:17:45.348818000
foo4-->1--->现在时间:00:17:45.350216000
foo4-->1--->现在时间:00:17:45.352800000
main 正在运行 ---> 1--->现在时间:00:17:45.355803000
main 正在运行 ---> 1--->现在时间:00:17:45.360606000
foo3-->2--->Time Now : 00:17:45.345305000 // // foo3 线程在按照 CFS 调度其他线程之前意外地第二次获得 CPU
foo3-->2--->现在时间:00:17:45.361666000
foo1-->1--->现在时间:00:17:45.354203000
foo1-->1--->现在时间: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_granularity_ns 值,任何任务都将执行该最短时间,如果任务需要超过该最短时间,则计算时间片,每个任务都将在该时间片内执行。
这里使用公式计算时间片,
时间片=(每个任务的权重/下所有任务的总权重 CFS 运行队列)x sched_latency_ns
谁能解释为什么我会得到这些调度结果???? 任何有助于理解输出的帮助将不胜感激。 提前谢谢你。
我在linux下使用gcc。
编辑 1:
如果我改变这个循环
for(int k=0;k
进入
for(int k=0;k
那么有时候线程 1 连续 10 次 CPU,线程 2 连续 5 次 CPU,线程 3 连续 5 次 CPU,主线程连续 2 次,线程 4 连续 7 次 CPU。看起来不同的线程在随机时间被抢占。
这些随机数次连续 CPU 分配给不同线程的任何线索。??
【问题讨论】:
标签: c++ linux multithreading pthreads posix