我正在尝试创建多个线程,并尝试找出调度顺序以及它们何时完成。每次线程获得CPU时,它都会执行一些计算,然后作为繁忙的等待时间等待x倍(1000ns),然后进入睡眠状态。每次一个线程获取CPU时,它也会打印时间,以便以后可以找到特定线程获取CPU的时间和顺序。
为了使线程安全,我正在使用互斥锁,但是仍然不能给出正确的结果。我在哪里犯错?任何帮助将不胜感激。
我在Linux下使用g ++。
注意:我无法使用文件,因为在这种情况下文件打开/关闭会产生开销。
这是我的程序输出
Output : $ sort -t , -k4,4n -k5,5n -k6,6n >a.txt
$ head a.txt
thread, thread_no, iteration, time_min, time_sec, time_microsec
foo,
foo,14,987
foo,32
foo,32,985,
foo,57,970
foo,71,933,
foo,71,933,
foo,71,933,
foo,71,933,
$ tail a.txt
thread, thread_no, iteration, time_min, time_sec, time_microsec
foo,98,991,40,05,935379
foo,98,992,40,05,935442
foo,98,993,40,05,935506
foo,98,994,40,05,935569 foo,98,995,40,05,935633 foo,98,996,40,05,935697 foo,98,997,40,05,935760 foo,98,998,40,05,935824 foo,98,999,40,05,937914 foo,98,1000,40,05,937994
根据Bart van Nierop在释放互斥锁之前添加out.flush()之后的评论,
这是结果。$ head a.txt
foo,
foo,
foo,48,991,
foo,65,
foo,95,
foo,97
foo,10,1,15,59,288329
foo,10,1,15,59,288329
foo,10,1,15,59,288329
这是我的程序
#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <sys/time.h>
#include <time.h> /* time_t, struct tm, time, localtime */
#include <mutex> // std::mutex
#include <sstream>
#define BILLION 1000000000L
#define NUM_THREADS 100
std::mutex mtx; // mutex for critical section
using namespace std;
std::string now_str()
{
struct timeval tv;
struct timezone tz;
struct tm *tm;
gettimeofday(&tv, &tz);
tm=localtime(&tv.tv_sec);
char buf[40];
sprintf(buf,"%02d,%02d,%ld ", tm->tm_min,tm->tm_sec, tv.tv_usec);
return buf;
}
std::ostringstream out;
/* This is our thread function. It is like main(), but for a thread*/
void *threadFunc(void *arg)
{
int s,j;
pthread_attr_t gattr;
// Assigning SCHED_RR policy
j = SCHED_RR;
s = pthread_attr_setschedpolicy(&gattr, j);
if (s != 0)
printf( "pthread_attr_setschedpolicy");
s = pthread_attr_getschedpolicy(&gattr, &j);
if (s != 0)
printf( "pthread_attr_getschedpolicy");
struct timespec start, stop;
double accum;
char *str;
int i = 0,k=0;
str=(char*)arg;
while(i < 1000)
{
++i;
// do something here
mtx.lock();
out << "\nfoo," <<str<<","<<i<<"," <<now_str(); // note the timing of thread
mtx.unlock();
if( clock_gettime( CLOCK_REALTIME, &start) == -1 )
{
perror( "clock gettime" );
exit( EXIT_FAILURE );
}
// busy wait for 1000ns
do
{
if( clock_gettime( CLOCK_REALTIME, &stop) == -1 )
{
perror( "clock gettime" );
exit( EXIT_FAILURE );
}
accum = ( stop.tv_sec - start.tv_sec )* BILLION + ( stop.tv_nsec - start.tv_nsec ) ;
}while(accum < 1000);
// block the thread, to allow other thread to run
usleep(1);
}
std::cout<<out.str();
return NULL;
}
int main(void)
{
pthread_t pth[NUM_THREADS];
int i = 0;
pthread_create(&pth[0],NULL, threadFunc, (void *) "0");
pthread_create(&pth[1],NULL, threadFunc, (void *) "1");
.
.
.
pthread_create(&pth[98],NULL, threadFunc, (void *) "98");
pthread_create(&pth[99],NULL, threadFunc, (void *) "99");
for(int k=0;k<NUM_THREADS;k++)
pthread_join(pth[k],NULL);
return 0;
}
在Google上稍作搜索,看来ostringstream不是线程安全的。
要获得所需的内容,可以滚动自己的日志记录。
一种方法是写入大缓冲区的末尾:
uint64_t offset = 0;
char buffer[ 200000 ];
使用互斥量写入:
mtx.lock();
offset += sprintf( buffer + offset, "\nfoo,%s,%d,%s", str, i, now_str().c_str() );
mtx.unlock();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句