Unix™ Systems Programming [Electronic resources] : Communication, Concurrency, and Threads

Prentice Hall

نسخه متنی -صفحه : 276/ 255
نمايش فراداده

22.10 Influence of Disk I/O

Disk accesses can be a million times slower than memory accesses. This section explores the effect of disk I/O on server performance.

To measure this performance, modify the various servers to access the disk rather than a memory buffer to satisfy requests. If your server selects from a small number of request files, your measurements may not be accurate because the operating system buffers file I/O and most of the requests may be satisfied from memory rather than from disk.

One possibility is to create a large number of files whose names are numeric, say, 00000, 00001, 00002, etc. When a request comes in, the server could pick one of these files at random and access it to satisfy the request. Some users might not have enough free disk space to implement this solution.

Another possibility is to use the system files that already exist. The idea is to create a list of the files on the server for which the user has read access. When a request comes in, the server randomly selects one of the files that is large enough to satisfy that request. Care must be taken to ensure that the process of selecting the file does not significantly burden the server.

Section 22.6, 22.7, 22.8 or 22.9 so that it satisfies requests from the disk rather than from a memory buffer. The server now takes two additional command-line arguments like those of Program 22.1 and creates the lists before accepting any connection requests. The server should display a message after creating the lists so that you can tell when to start your clients. Compare the results with those of the corresponding server that did not access the disk.

Program 22.1 makefileinfo.c

A program that creates a list of files by walking through a directory tree.

#include <fcntl.h>
#include <ftw.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "restart.h"
#define MAXPATH 100
#define NUMRANGES 5
typedef struct {
off_t filesize;
char path[MAXPATH+1];
} fileinfo;
static int filecounts[NUMRANGES];
static fileinfo *files[NUMRANGES];
static int maxnum;
static int whichlist(off_t size) {
int base = 10;
int limit;
int lnum;
if (size < base)
return -1;
for (lnum = 0, limit = base*base;
lnum < NUMRANGES - 1;
lnum++, limit *= 10)
if (size < limit)
break;
return lnum;
}
static int insertfile(const char *path, const struct stat *statbuf,
int info, struct FTW *ftwinfo) {
int fd;
int lnum;
static int numfull = 0;
if (info != FTW_F)
return 0;
if (strlen(path) > MAXPATH)
return 0;
if ((statbuf->st_mode & S_IFREG) == 0)
return 0;
if ((fd = open(path, O_RDONLY | O_NONBLOCK)) == -1)
return 0;
if (r_close(fd) == -1)
return 0;
lnum = whichlist(statbuf->st_size);
if (lnum < 0)
return 0;
if (filecounts[lnum] == maxnum)
return 0;
strcpy(files[lnum][filecounts[lnum]].path, path);
files[lnum][filecounts[lnum]].filesize = statbuf->st_size;
filecounts[lnum]++;
if (filecounts[lnum] == maxnum) numfull++;
if (numfull == NUMRANGES)
return 1;
return 0;
}
void showfiles(int which) {
int i;
fprintf(stderr, "List %d contains %d entries\n", which, filecounts[which]);
for (i = 0; i < filecounts[which]; i++)
fprintf(stderr, "%*d: %s\n",which + 6,files[which][i].filesize,
files[which][i].path);
}
int main(int argc, char *argv[]) {
int depth = 10;
int ftwflags = FTW_PHYS;
int i;
if (argc != 3) {
fprintf(stderr, "Usage: %s directory maxnum\n", argv[0]);
return 1;
}
maxnum = atoi(argv[2]);
for (i = 0; i < NUMRANGES; i++) {
filecounts[i] = 0;
files[i] = (fileinfo *)calloc(maxnum, sizeof(fileinfo));
if (files[i] == NULL) {
fprintf(stderr,"Failed to allocate memory for list %d\n", i);
return 1;
}
}
fprintf(stderr, "Max number for each range is %d\n", maxnum);
if (nftw(argv[1], insertfile, depth, ftwflags) == -1) {
perror("Failed to execute nftw");
return 1;
}
fprintf(stderr, "**** nftw is done\n");
fprintf(stderr, "Counts are as follows with sizes at most %d\n", maxnum);
for (i = 0; i < NUMRANGES; i++)
fprintf(stderr, "%d:%d\n", i, filecounts[i]);
for (i = 0; i < NUMRANGES; i++)
showfiles(i);
return 0;
}