多线程文件拷贝。
#include <error.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "restart.h"
#define MAXNAME 80
#define R_FLAGS O_RDONLY
#define W_FLAGS (O_WRONLY | O_CREAT)
#define W_PERMS (S_IRUSR | S_IWUSR)
#define R_PERMS (S_IRWXU|S_IRWXG|S_IRWXO)
typedef struct
{
int args[3];
pthread_t tid;
char acInputFilePath[MAXNAME];
char acOutputFilePath[MAXNAME];
} copy_t;
void *copyfilepass(void *arg)
{
int *argint;
argint =(int *)arg;
argint[2] = copyfile(argint[0], argint[1]);
r_close(argint[0]);
r_close(argint[1]);
return argint + 2;
};
int main( int argc, char *argv[] )
{
int *bytesp;
copy_t *copies;
int error;
int i;
int numcopiers;
int totalbytes;
#if 0
if (argc != 4)
{
fprintf(stderr, "Usage: %s infile outfile copies\n", argv[0]);
return 1;
}
numcopiers = atoi(argv[3]);
#endif
numcopiers = argc - 1;
if ((copies = (copy_t *)calloc(numcopiers, sizeof(copy_t))) == NULL)
{
perror("Failed to allocate copier spaces");
return 1;
}
for(i = 0; i < numcopiers; i++)
{
copies[i].tid = pthread_self();
#if 0
if (snprintf(filename, MAXNAME, "%s.%d", argv[1], i+1) == MAXNAME)
{
fprintf(stderr, "Input filename %s.%d too long ", argv[i], i + 1);
continue;
}
#endif
strcpy(copies[i].acInputFilePath, argv[i+1]);
strcat(copies[i].acOutputFilePath,"des");
// char *pPoint = strrchr(copies[i].acInputFilePath,'/');
strcat(copies[i].acOutputFilePath,copies[i].acInputFilePath);
if ((copies[i].args[0] = open(copies[i].acInputFilePath, R_FLAGS)) == -1)
{
fprintf(stderr, "Failed to open source file %s: %s\n",copies[i].acInputFilePath, strerror(error));
continue;
}
if ((copies[i].args[1] = open(copies[i].acOutputFilePath, W_FLAGS, W_PERMS)) == -1)
{
fprintf(stderr, "Failed to open destination file %s: %s\n", copies[i].acOutputFilePath, strerror(error));
continue;
}
if( error = pthread_create(&copies[i].tid, NULL, copyfilepass, copies[i].args))
{
fprintf(stderr, "Failed to create thread %d: %s\n", i +1, strerror(error));
copies[i].tid = pthread_self();
}
}
for(i = 0; i < numcopiers; i++)
{
if (pthread_equal(copies[i].tid, pthread_self()))
{
continue;
}
if (error = pthread_join(copies[i].tid, (void **) &bytesp))
{
fprintf(stderr, "Failed to join thread %d\n",i);
continue;
}
if (bytesp == NULL)
{
fprintf(stderr, "thread %d Failed to return status\n", i);
continue;
}
printf("Thread %d copied %d bytes from %s.%d to %s.%d\n",i, *bytesp, argv[1], i + 1, argv[2], i + 1);
totalbytes += *bytesp;
}
printf("Total bytes copies = %d\n", totalbytes);
return 0;
}
restart.h
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#ifndef ETIME
#define ETIME ETIMEDOUT
#endif
ssize_t r_read( int fd, void *buf, size_t size);
ssize_t r_write( int fd, void *buf, size_t size);
int r_close( int fildes );
int copyfile( int fromfd, int tofd );
restart.c
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/wait.h>
#include "restart.h"
#define BLKSIZE (4*1024)
#define MILLION 1000000L
#define D_MILLION 1000000.0
ssize_t r_write( int fd, void *buf, size_t size)
{
char *bufp;
size_t bytestowrite;
ssize_t byteswritten;
size_t totalbytes;
for ( bufp = buf, bytestowrite = size, totalbytes = 0; bytestowrite > 0; bufp += byteswritten, bytestowrite -= byteswritten )
{
byteswritten = write(fd, bufp, bytestowrite);
if ((byteswritten) == -1 && (errno != EINTR))
return -1;
if (byteswritten == -1 )
{
byteswritten = 0;
totalbytes += byteswritten;
}
return totalbytes;
}
}
ssize_t r_read(int fd, void *buf, size_t size)
{
ssize_t retval;
while (retval = read(fd, buf, size), retval == -1 && errno == EINTR);
return retval;
}
int r_close( int fildes )
{
int retval;
while( retval = close( fildes), retval == -1 && errno == EINTR );
return retval;
}
int copyfile( int fromfd, int tofd )
{
char *bp;
char buf[BLKSIZE];
int bytesread;
int byteswritten = 0;
int totalbytes = 0;
while ( 1 ==1 )
{
while ( (( bytesread = read( fromfd, buf, BLKSIZE )) == -1 ) & ( errno == EINTR ));
if (bytesread <= 0)
{
break;
}
bp = buf;
while ( bytesread > 0 )
{
while ( (( byteswritten = write( tofd, bp, bytesread )) == -1 ) && ( errno == EINTR ));
if (byteswritten < 0 )
break;
totalbytes += byteswritten;
bytesread -= byteswritten;
bp += byteswritten;
}
if ( byteswritten == -1 )
{
break;
}
}
return totalbytes;
}
Makefile
copyfile: copymultiple.o restart.o
gcc -o copyfile copymultiple.o restart.o -lpthread
copymultiple.o:copymultiple.c restart.h
gcc -c copymultiple.c
restart.o:restart.c restart.h
gcc -c restart.c
clean:
rm -rf copymultiple.o restart.o