QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 942|回复: 0

读文件问题,哪位大哥能从内核的角度指点指点

[复制链接]
发表于 2005-3-2 16:58:02 | 显示全部楼层 |阅读模式
小弟初学linux

下面是我的程序:

// linuxtest.c: Defines the entry point for the console application.
//
//#include <linux/slab.h>
//#include <linux/stat.h>
//#include <linux/fcntl.h>
//#include <linux/file.h>
//#include <linux/uio.h>
//#include <linux/smp_lock.h>
//#include <linux/dnotify.h>

//#include <asm/uaccess.h>

#include <asm/unistd.h>
#include <sys/stat.h>
//#include <string.h>
#include <fcntl.h>
//#include <stdio.h>
//#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <sys/timeb.h>
//#include <sys/types.h>
//#include <sys/resource.h>
//#include <linux/param.h>

/////////////////////////////////////////////////////////////////////////////
// The one and only application object
#define BUFFERSIZE 1024*1024*3
#define WIBLOCK 30
//char Bp2[BUFFERSIZE];
char Bp1[BUFFERSIZE]; //读文件缓冲区
long startSeconds; //开始时间(秒)
long startMilli; //开始时间(微秒)
long finishSeconds; //结束时间(秒)
long finishMilli; //结束时间(微秒)
long rate=0; //读取速度
struct timeb* timeBuffer; //时间缓冲区
char FName[66][8]={"1.rar","2.rar","3.rar", //文件名数组
"4.rar","5.rar","6.rar","7.rar",
"8.rar","9.rar","10.rar","11.rar",
"12.rar","13.rar","14.rar",
"15.rar","16.rar","17.rar",
"18.rar","19.rar","20.rar",
"21.rar","22.rar","23.rar",
"24.rar","25.rar","26.rar",
"27.rar","28.rar","29.rar",
"30.rar","31.rar","32.rar",
"33.rar","34.rar","35.rar",
"36.rar","37.rar","38.rar",
"39.rar","40.rar","41.rar",
"42.rar","43.rar","44.rar",
"45.rar","46.rar","47.rar",
"48.rar","49.rar","50.rar",
"51.rar","52.rar","53.rar",
"54.rar","55.rar","56.rar",
"57.rar","58.rar","59.rar",
"60.rar"};
char fileInBuffer[1024*500]; //输出文件缓冲区
int randSelect[100]; //文件名选取数组
long cost=0; //读取消耗时间
static void *myProcess(void *arg); //线程执行函数
//extern ssize_t sys_read(unsigned int,char*,size_t);
int consol(); //可变参数输入函数
int threadNum; //线程标号
int totalTimes=0; //读取次数
int endFlag; //读取结束标志
int g_iThreadNum; //线程总数
int g_iFileNum; //文件总数
int g_iBlockSize; //块大小(每调用一次read读取块)
int g_iTotalBlocks; //块数
int g_iThreadReadTimes; //每个线程读文件个数
int g_iSizeSelect; //每个文件读取次数
pthread_mutex_t g_iMutex=PTHREAD_MUTEX_INITIALIZER; //互斥
//pthread_mutex_t g_iMutex2=PTHREAD_MUTEX_INITIALIZER;
int main()
{
//long buffer[32767];
int times;
long k;
long f;
char fBuffer[200];
while(!consol()){};
endFlag=g_iThreadNum*g_iThreadReadTimes;
threadNum=g_iThreadNum;
sprintf(fBuffer,"***********************************************\n Read test in linux! \n %dM/PER FILE \n***********************************************\n\0",g_iSizeSelect*g_iTotalBlocks*g_iBlockSize);
strcat(fileInBuffer,fBuffer);
/*srand(time((time_t*)NULL));
for(f=0;f<g_iFileNum*(g_iThreadNum);f++)
{
for(k=0;k<32767;k++)
{
buffer[k]=rand();
}
randSelect[f]=(buffer[18000])%g_iFileNum;
}*/
for(f=0;f<g_iFileNum;f++){
randSelect[f]=f;
}
timeBuffer=(struct timeb *)malloc(sizeof(struct timeb));
ftime(timeBuffer);
startSeconds = timeBuffer->time;
startMilli=timeBuffer->millitm;
//pthread_mutex_init(&g_iMutex,PTHREAD_MUTEX_INITIALIZER);
for(times=0;times<g_iThreadNum;times++)
{
pthread_t pid;
pthread_attr_t* attr;
struct sched_param* param;
param=(struct sched_param*)malloc(sizeof(struct sched_param));
attr=(pthread_attr_t*)malloc(sizeof(pthread_attr_t));
param->sched_priority=0;
pthread_attr_init(attr);
pthread_attr_setscope(attr,PTHREAD_SCOPE_SYSTEM);
//pthread_attr_setdetachstate(attr,PTHREAD_CREATE_DETACHED);
pthread_attr_setschedpolicy(attr,SCHED_RR);
pthread_attr_setschedparam(attr,param);
pthread_create(&pid,attr,myProcess,NULL );
free(attr);
free(param);
//setpriority(PRIO_PROCESS,pid,-20);
//*myProcess(NULL);
}
sleep(999);
//while(1){};
}

static void *myProcess(void *arg){
//int mutexSelect;
int download=0;
int timeOutTimes=1;
int perBlockRate;
int l_iFileSize;
int handle;
int readTimes;
int currentID;
int currentTimes;
int localEndFlag;
int hfile;
int k;
int lockTimes=0;
char *Bp;
const char* p;
unsigned short firstIn=1; //Circl first in flag
char fBuffer[WIBLOCK];
//long start, finish;
long ownTimeStartSeconds,ownTimeFinishSeconds,ownTimeStartMilli,ownTimeFinishMilli;
long perFileCost=0;
long perBlockLastSeconds=0,perBlockLastMilli=0,perBlockCurrentSeconds=0,perBlockCurrentMilli=0;
threadNum--;
currentID=threadNum;
for(readTimes=0;readTimes<g_iThreadReadTimes;readTimes++){
totalTimes++;
currentTimes=totalTimes;
p=FName[randSelect[readTimes*g_iThreadNum+currentID]];
hfile=open(p,O_RDONLY);
//Bp=(char*)malloc(BUFFERSIZE);

ftime(timeBuffer);
ownTimeStartSeconds = timeBuffer->time;
ownTimeStartMilli=timeBuffer->millitm;
for(l_iFileSize=0;l_iFileSize<g_iTotalBlocks;l_iFileSize++){
if(currentID>(g_iThreadNum/2-1)){
pthread_mutex_lock(&g_iMutex);
Bp=Bp1;
lockTimes++;
//printf("\n>14 %d",currentID);
}
else {
pthread_mutex_lock(&g_iMutex);
Bp=Bp1;
lockTimes++;
//printf("\n<14 %d",currentID);
}
ftime(timeBuffer);
perBlockCurrentSeconds = timeBuffer->time;
perBlockCurrentMilli = timeBuffer->millitm;
if(!firstIn){
perBlockRate=perBlockCurrentMilli+(perBlockCurrentSeconds-perBlockLastSeconds)*1000-perBlockLastMilli;
if(perBlockRate>(g_iSizeSelect*g_iBlockSize*1000)){
perBlockRate=perBlockCurrentMilli+(perBlockCurrentSeconds-perBlockLastSeconds)*1000-perBlockLastMilli;
printf("\nDownload: %dM Time of Next Block read: %ld Timeout: %d",download,perBlockRate,timeOutTimes);
//sprintf(fBuffer,"\nDownload: %dM Time of Next Block read: %ld ",download,perBlockRate);
timeOutTimes++;
//strcat(fileInBuffer,fBuffer);
perBlockLastSeconds = perBlockCurrentSeconds;
perBlockLastMilli = perBlockCurrentMilli;
}
}else {
firstIn=0;
perBlockLastSeconds = perBlockCurrentSeconds;
perBlockLastMilli = perBlockCurrentMilli;
}
perBlockLastSeconds = perBlockCurrentSeconds;
perBlockLastMilli = perBlockCurrentMilli;
for(k=0;k<g_iSizeSelect;k++) read(hfile,Bp,1024*1024*g_iBlockSize);
if(currentID>(g_iThreadNum/2-1)) pthread_mutex_unlock(&g_iMutex);
else pthread_mutex_unlock(&g_iMutex);
download+=g_iBlockSize*g_iSizeSelect;
//printf("\nThread %d mutex locked Times: %d",currentID,download);
sleep(0);
}
ftime(timeBuffer);
ownTimeFinishSeconds = timeBuffer->time;
ownTimeFinishMilli=timeBuffer->millitm;
ownTimeFinishMilli+=(ownTimeFinishSeconds-ownTimeStartSeconds)*1000;
perFileCost=ownTimeFinishMilli-ownTimeStartMilli;
endFlag--;
localEndFlag=endFlag;
//sprintf(fBuffer,"\n Thread %d Filename: %s Readtimes: %d Cost: %ld",currentID,p,currentTimes,perFileCost);
sprintf(fBuffer,"\n Thread %d ",currentID);
//myStrCat(fileInBuffer,fBuffer,sizeof(fileInBuffer),sizeof(fBuffer));
strcat(fileInBuffer,fBuffer);
sprintf(fBuffer,"Filename: %s ",p);
strcat(fileInBuffer,fBuffer);
sprintf(fBuffer,"Readtimes: %d ",currentTimes);
strcat(fileInBuffer,fBuffer);
sprintf(fBuffer,"Cost: %ldms ",perFileCost);
strcat(fileInBuffer,fBuffer);
rate+=(g_iSizeSelect*g_iTotalBlocks*g_iBlockSize*1024*1000)/(perFileCost);
//printf("\nLocked times: %d",lockTimes);
printf("\nThread %d Filename: %s Readtimes: %d Cost: %ld,Average Speed is %ld K/S",currentID,p,currentTimes,perFileCost,((g_iSizeSelect*g_iTotalBlocks*g_iBlockSize*1000*1024)/(perFileCost)));
sprintf(fBuffer,"Rate: %ldK/S\n",((g_iSizeSelect*g_iTotalBlocks*g_iBlockSize*1000*1024)/(perFileCost)));
strcat(fileInBuffer,fBuffer);
//free(Bp);
close(hfile);
}

if(!localEndFlag) {
ftime(timeBuffer);
finishSeconds = timeBuffer->time;
finishMilli=timeBuffer->millitm;
finishMilli+=(finishSeconds-startSeconds)*1000;
cost+=finishMilli-startMilli;
printf("\nThread number: %d File number: %d Block size: %dM Total times:%d Cost:%8ld \n",g_iThreadNum,g_iFileNum,g_iBlockSize,g_iThreadNum*g_iThreadReadTimes,cost);
sprintf(fBuffer,"\nThread number: %d File number: %d ",g_iThreadNum,g_iFileNum);
strcat(fileInBuffer,fBuffer);
sprintf(fBuffer,"Block size: %dM Total times: %d Cost: %ldms ",g_iBlockSize,g_iThreadNum*g_iThreadReadTimes,cost);
strcat(fileInBuffer,fBuffer);
sprintf(fBuffer,"Avrage Rate: %ldK/S \n",(rate/((g_iThreadNum)*g_iThreadReadTimes)));
strcat(fileInBuffer,fBuffer);
handle = creat("history.txt", S_IREAD | S_IWRITE);
write(handle, fileInBuffer, strlen(fileInBuffer));
close(handle);
}
//while(1){};
return NULL;
}
int consol()
{
printf("\nIs Linuxtest2\n"); //线程总数
printf("\nPlease input Thread number(integer): ");
scanf("%d",&g_iThreadNum); //文件总数
printf("\nPlease input fileNum(integer): ");
scanf("%d",&g_iFileNum);
if ((g_iFileNum)>61){ printf("\n File number must <62");return 0;}
printf("\nPlease input blockSize(integer): ");
scanf("%d",&g_iBlockSize); //块大小
printf("\nPlease input total blocks to read: ");
scanf("%d",&g_iTotalBlocks); //每次读的块数
printf("\nPlease input ThreadReadTimes(per thread read times Integer type): ");
scanf("%d",&g_iThreadReadTimes); //每个线程读文件个数
printf("\nPlease input SizeSelect: ");
scanf("%d",&g_iSizeSelect); //每个文件读取次数
return 1;
}
//文件大小=块大小*每次读的块数*每个文件读取次数


以上是小弟写的测试程序,目的是测试Linux下多线程读文件的速度

读取方式是这样的:调用系统调用read,每个文件分几次读取,利用互斥给线程加锁,这样保证同一时间内只有一个线程读文件(为了减少用于磁头移动消耗的时间),结果发现每个线程每次读取的速度很不稳定,如何让这个速度稳定些啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-16 10:43 , Processed in 0.037230 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表