|
最近在看Alex Vrenios的《Linux集群体系结构》,里面的客户程序我如何也调试不出,希望高手给够指点。
源程序如下
[code:1]
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "msi.h"
#define FALSE 0
#define TRUE 1
#define NUM 50
#define CATS 10 /* # of response time categories */
#define cats [CATS] = {.1, .2, .3, .4, .5, .6, .7, .8, .9, .10};
int bars[CATS] = { 0 }; /* counters for bar chart */
int main(int argc, char *argv[])
{
/*
** client.c: reports response time stats
*/
struct timeval bef, aft; /* timer value before/after */
struct sockaddr_in sock;
struct hostent *hp;
int flag = (IPC_CREAT | IPC_EXCL | 0660);
int size = NUM * sizeof(double);
key_t key = 0x01234567; /* example shared memory key */
int shmid; /* shared memory area id */
int Expon = FALSE; /* boolean: exponential dist */
int Pulse = FALSE; /* boolean: pulse distribution */
int Sweep = FALSE; /* boolean: sweep distribution */
double mean = 0.50; /* mean value for exponential */
double slow = 0.25; /* slow value for pulse & sweep */
double fast = 0.10; /* fast value for pulse burst */
double random; /* random reals: 0.0 -> 1.0 */
double delay; /* calculated delay time */
double *rt; /* response times from subtasks */
long timeleft; /* time remaining in IAT */
long usec = 0L; /* inter-arrival microseconds */
long secs = 0L; /* time remaining in seconds */
int pids[NUM]; /* subtask process ids */
int opt = 1; /* setsockopt parameter */
int fd; /* socket file descriptor */
int ii, jj, kk = 0;
char distribution[4];
char buf[QUERYSIZE], *p;
int status;
srand((unsigned int) getpid()); /* seed rand() */
/*
** Operands are remote HOST name and distribution code
*/
if (argc != 3) {
printf("\n\tUsage: %s <HOST> <DISTRIBUTION>\n\n", argv[0]);
exit(-1);
}
hp = gethostbyname(argv[1]);
if ((argv[2][0] == 'e') || (argv[2][0] == 'E')) {
Expon = TRUE;
strcpy(distribution, "EXP");
srand((unsigned int) getpid()); /* rand() seed */
} else if ((argv[2][0] == 'p') || (argv[2][0] == 'P')) {
Pulse = TRUE;
strcpy(distribution, "PLS");
} else if ((argv[2][0] == 's') || (argv[2][0] == 'S')) {
Sweep = TRUE;
strcpy(distribution, "SMP");
} else {
printf("\n\tUsage: %s <HOST> <DISTRIBUTION>\n", argv[0]);
printf("\t DISTRIBUTION = { 'e' | 'p' | 's' }\n");
printf("\t for exponential, pulse and sweep\n\n");
exit(-1);
}
/* attach shared memory array */
shmid = shmget(key, size, flag);
/* attach the shared memory area */
rt = (double *) shmat(shmid, 0, 0);
/*
** LOOP : send and receive NUM packets
*/
for (ii = 0; ii < NUM; ii++) {
rt[ii] = 0.0; /* zero shared array values */
if (Expon) {
random = rand() / (double) RAND_MAX;
delay = -mean * log(random);
if (delay > 0.999999) {
delay = 0.999999; /* limit maximum */
}
} else if (Pulse) {
if ((ii > (NUM * 0.3)) && (ii < (NUM * 0.4))) {
delay = fast;
} else {
delay = slow;
}
} else if (Sweep) {
delay = slow - (ii * (slow / NUM));
} else {
printf("\n\tError in logic?\n\n");
exit(-1);
}
secs = (long) delay;
usec = (long) (1000000.0 * (delay - ((double) secs)));
/* random line numbers: 1 thru 99 */
random = rand() / (double) RAND_MAX;
jj = (int) ((double) (99.0) * random) + 1;
if (jj == 20) {
jj = 99;
}
sprintf(buf, "/home/andy/src/cluster/main/sample.txt %d", jj);
/* record sending time */
gettimeofday(&bef, NULL);
/*
** A subtask for each query/response
*/
if ((pids[kk++] = fork()) == 0) {
/* attach parent's shared memory */
rt = (double *) shmat(shmid, 0, 0);
/* shmid is still set correctly */
/* Set up TCP socket to the server */
fd = socket(AF_INET, SOCK_STREAM, 0);
memset((char *) &sock, 0, sizeof(sock));
memcpy(&sock.sin_addr, hp->h_addr, hp->h_length);
sock.sin_family = hp->h_addrtype;
sock.sin_port = htons(QUERYPORT);
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt,
sizeof(opt));
connect(fd, (struct sockaddr *) &sock, sizeof(sock));
send(fd, buf, strlen(buf) + 1, 0);
/* await result from server */
buf[0] = 0; /* clear buffer */
if (recv(fd, buf, QUERYSIZE, 0) > 0) {
printf("\t%d. Line %2d: %s ", kk, jj, buf);
p = strrchr(buf, ' ') + 2;
if (jj != atoi(p)) {
printf("***"); /* incorrect result! */
}
printf("\n");
}
/* record response time */
gettimeofday(&aft, NULL);
aft.tv_sec -= bef.tv_sec;
aft.tv_usec -= bef.tv_usec;
if (aft.tv_usec < 0L) {
aft.tv_usec += 1000000L;
aft.tv_sec -= 1;
}
rt[ii] =
(double) aft.tv_sec + ((double) aft.tv_usec / 1000000.0);
close(fd);
exit(0);
}
/*
** Sleep for remainder of IAT
*/
gettimeofday(&aft, NULL);
aft.tv_sec -= bef.tv_sec;
aft.tv_usec -= bef.tv_usec;
if (aft.tv_usec < 0L) {
aft.tv_usec += 1000000L;
aft.tv_sec -= 1;
}
bef.tv_sec = secs;
bef.tv_usec = usec;
bef.tv_sec -= aft.tv_sec;
bef.tv_usec -= aft.tv_usec;
if (bef.tv_usec < 0L) {
bef.tv_usec += 1000000L;
bef.tv_sec -= 1;
}
timeleft = (bef.tv_sec * 1000000L) + bef.tv_usec;
if (timeleft < 0) {
printf("\tERROR: A higher IAT value is required - exiting.\n");
break;
}
usleep(timeleft);
}
for (ii = 0; ii < kk; ii++) {
waitpid(pids[ii], &status, 0);
}
/*
** Report the response time statistics
*/
for (ii = 0; ii < NUM; ii++) {
for (jj = 0; jj < CATS; jj++) {
if (rt[ii] < cats[jj]) {
bars[jj]++;
break;
}
}
}
sleep(2);
printf("RESPONSE | %3d QUERY PACKETS %s\n",
NUM, distribution);
printf("TIME (msec) | 10 20 30 40 50\n");
printf("------------+---+---+---+----+---+----+---+----+---+--+\n");
ii = 0; /* total */
for (jj = 0; jj < CATS; jj++) {
ii += bars[jj];
kk = (1000.0 * cats[jj]) + .5;
printf(" %5d%5d |", kk - 9, kk);
for (kk = 0; kk < bars[jj]; kk++) {
printf("*");
}
printf("\n");
}
printf(" OVER%5d |", (int) (1000 * cats[CATS - 1]));
jj = NUM - ii;
for (kk = 0; kk < jj; kk++) {
printf("*");
}
printf("\n");
/* remove unused shared memory area and exit */
shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0);
return 0;
}
[/code:1][/code] |
|