写一段操作文件的程序,要求先读取一个文件再对文件进行顺序、随机写。要求能够对文件进行同步和异步写
程序1:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
char* tf ="/var/log/glusterfs/offsets";
char* tg = "/var/lib/nova/instances/testdata";
int main(int argc, char* argv) {
intfd = -1;
inti = 0;
char* buf = NULL;
off_t offsets[40000];
FILE* fp = NULL;
char line[1024];
intj = 0;
fp= fopen(tf, "r");
if(fp == NULL) {
return -1;
}
memset(line, '\0', 1024);
while ( fgets(line, 1023, fp) != NULL) {
offsets[j++] = atol(line);
}
fclose(fp);
//fd = open(tg, O_RDWR | O_DSYNC | O_CLOEXEC) ;
fd= open(tg, O_RDWR) ;
if (fd < 0) {
printf("Failed to open file %s\n", tg);
return -1;
}
buf= (char*)malloc(131072);
if(buf == NULL) {
printf ("Failed to malloc buffer.\n");
return -1;
}
for( i = 0; i <= j; i++) {
lseek(fd, offsets[i], SEEK_SET);
int res = write(fd, buf, 131072);
if ( res != 131072 ) {
printf ("Failed\n");
close(fd);
return -1;
}
}
close(fd);
return 0;
}
Memset用于初始化
为什么要用memset
程序2
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
pthread_mutex_t mutex; //declare a mutex lock
size_t offsets[200]; //size_t is unsigned int in c library
size_t sizes[200] = {
5734400, 32768, 32768, 7897088, 8388608, 8388608, 8388608, 8388608, 8388608, 8388608,
8388608, 8388608, 524288, 7864320, 8388608, 7864320, 8388608, 8388608, 8388608, 524288,
8388608, 7864320, 524288, 8388608, 8388608, 8388608, 7864320, 7864320, 524288, 8388608,
7864320, 524288, 8388608, 524288, 1572864, 7864320, 524288, 1048576, 7340032, 8388608,
8912896, 8388608, 1572864, 524288, 1572864, 5767168, 8388608, 8388608, 1048576, 5767168,
7864320, 1572864, 524288, 1572864, 1572864, 8388608, 7864320, 7864320, 8388608, 5767168,
1572864, 2097152, 5767168, 1572864, 1048576, 1048576, 7864320, 7864320, 7864320, 2097152,
524288, 7340032, 1572864, 7864320, 1048576, 7864320, 5767168, 3670016, 1572864, 524288,
5767168, 2097152, 4718592, 7864320, 1048576, 4194304, 2621440, 7864320, 1572864, 2621440,
1572864, 1048576, 5242880, 5767168, 2621440, 8388608, 8388608, 2621440, 1048576, 12058624,
2621440, 11534336, 8388608, 8388608, 1572864, 1572864, 5242880, 1048576, 8388608, 2097152,
11534336, 3670016, 1572864, 4194304, 1048576, 8388608, 6815744, 3145728, 4718592, 11534336,
8388608, 1048576, 1048576, 4194304, 8388608, 7864320, 5767168, 2097152, 2621440, 7864320,
4194304, 1572864, 1048576, 1048576, 1048576, 1048576, 7864320, 3145728, 2097152, 4718592,
3670016, 4194304, 4194304, 8388608, 2097152, 5242880, 4718592, 14155776, 4718592, 4194304,
3670016, 3670016, 8388608, 5242880, 2097152, 1572864, 2097152, 1572864, 4194304, 8388608,
3670016, 2621440, 3145728, 5242880, 14155776, 1572864, 2621440, 2097152, 4194304, 5767168,
5767168, 1572864, 2097152, 5242880, 3145728, 3670016, 2621440, 1572864, 8388608, 5242880,
2621440, 3670016, 5242880, 1572864, 11010048, 2097152, 1572864, 3670016, 2097152, 1572864,
4194304, 3145728, 5242880, 3670016, 1572864, 3145728, 3145728, 5242880, 2621440, 1638400
};
size_t idx = 0;
int fd = -1;
/*把buf中的内容写到文件fd中,从文件的off处开始写,一共写sz个字节*/
int writeall(char* buf, size_t off, size_t sz)
{
int ret = 0;
while (sz > 0) {
// writes up to count bytes from the buffer starting at buf to the file descriptor fd at offsetoffset. The file offset is not changed.
ret = pwrite(fd, buf, sz, off);
//On success, the number of bytes written is returned, or -1 on error, in which case errno is set to indicate the error.
if (ret > 0) {
sz -= ret;
off += sz;
} else {
printf("Failed to write.\n");
return ret;
}
}
//上述代码中为什么使用while,而不直接pwrite呢?主要是担心pwrite写过程出错,还有机会再写剩下的部分,所以老手写代码就是不一样。
return sz;
}
void * thread_func()
{
size_t i, off, sz;
char* buf = NULL;
buf = (char*)malloc(1024 * 1024 * 16); //
while (1) {
pthread_mutex_lock(&mutex);
i = idx++;
pthread_mutex_unlock(&mutex);
if (i >= 200) {
return;
}
off = offsets[i];
sz = sizes[i];
if (fd >= 0) {
printf("Write %ld bytes from %ld.\n", sz, off);
if (writeall(buf, off, sz) < 0) {
return ;
}
}
}
}
/*计算出每个线程写的具体位置*/
int prepare_offset()
{
int i = 0;
size_t sum = 0;
for (i = 0; i < 200; i++) {
offsets[i] = sum;
sum += sizes[i];
}
}
int main(int argc, char* argv[])
{
int i = 0, nth;
pthread_t* th;
if (argc < 3) {
printf("Usage: multiwrite filepath nthreads.\n");
return -1;
}
nth = atoi(argv[2]);
if (nth < 1 || nth > 32) {
printf("Thread number should bigger than 0 and less than 32.\n");
return -1;
}
th = (pthread_t*) malloc(sizeof(pthread_t) * nth);
pthread_mutex_init(&mutex, NULL);
fd = open(argv[1], O_CREAT | O_SYNC | O_RDWR, 0755);
if (fd < 0) {
if (errno = EEXIST) {
fd = open(argv[1], O_SYNC | O_RDWR) ;
}
if (fd < 0) {
printf("Failed to open file %s.\n", argv[1]);
return -1;
}
}
prepare_offset();
/* Create independent threads each of which will execute function */
for (i = 0; i < nth; i++) {
pthread_create(&th[i], NULL, thread_func, NULL);
}
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
for (i = 0; i < nth; i++) {
pthread_join(th[i], NULL);
}
pthread_mutex_destroy(&mutex);
return 0;
}
1. pread, pwrite - read from or write to a file descriptor at a given offset 。
2. 编译多线程程序: gcc ./multhread.c -o syncmulthread -lpthread
3. open函数使用(O_SYNC)和(O_ASYNC)性能相差巨大。