回 帖 发 新 帖 刷新版面

主题:求解:想写个用mmap实现多线程拷贝的程序,

刚刚学的多线程,还不是特熟。我是想在当前目录下实现文件拷贝,思路是这样:mmap创建两个映射区,分别对应源文件和目标文件。准备使用5个线程实现拷贝,线程创建时传入线程的编号(第几个),用于决定每个线程拷贝多少字节。在线程函数里对mmap映射区操作,我现在运行是段错误。。。gdb又不太会调。。。愁死我了。。。

下面是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>

#define THD 5

char *src,*tar;
int len,m,n;

void err_sys(char *str)
{
    perror(str);
    exit (1);
}

void *tfn(void *arg)
{
    int i,num = (int)arg;
    char *l,*r;
    l = src;
    r = tar;
    l += num * m;
    r += num * m;

    if(num != THD - 1)
    {
        for(i = 0; i < m; i++)
          *(r + i) = *(l + i);
    }
    else
    {
        for(i = 0; i < n; i++)
          *(r + i) = *(l + i);
    }

    return NULL;
}

int main(int argc, char **argv)
{
    int op,ip,i,err;
    pthread_t tid[THD];

    if(argc != 3)
      err_sys("Input Error");

    ip = open(argv[1],O_RDONLY);
    if(ip < 0)
      err_sys("open failed");

    op = open(argv[2],O_RDWR | O_CREAT | O_TRUNC,0644);
    if(op < 0)
      err_sys("open failed");

    len = lseek(ip,0,SEEK_END);
    m = len / THD; n = len - (THD - 1) * m;

    lseek(op,len - 1, SEEK_SET);
    write(op, "a", 1);

    src = (char*)mmap(NULL, len, PROT_READ, MAP_SHARED, ip, 0);
    if(src == MAP_FAILED)
        err_sys("mmap failed");
    tar = (char*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, op, 0);
    if(tar == MAP_FAILED)
        err_sys("mmap failed");
    close(ip);
    close(op);

    tid = (pthread_t *)malloc(sizeof(pthread_t) * THD);
    for(i = 0; i < THD; i++)
    {
         if ((err = pthread_create(&tid[i],NULL,tfn,(void*)i)) != 0)
             err_sys("- -! --> thread failed!");
    }
    for(i = 0; i < THD; i++)
      pthread_join(tid[i], NULL);

    munmap(src,len);
    munmap(tar,len);

    return 0;
}

回复列表 (共5个回复)

沙发

没用,肯定不如用一个线程快。
因为磁盘读取是无法并行的

板凳

学习了

3 楼


- -!我只是想运用下刚学到的知识,现在碰到问题想请人帮看看而已- -。

4 楼

基本没玩过linux,不过还是有发现问题的:


问题一:
void *tfn(void *arg)
{
    int i,num = atoi(arg);

注意arg实际上是main函数传进去的(void*)i,所以atoi的写法势必不正确。只要num = (int)arg即可。


问题二:
pthread_t *tid;
if ((err = pthread_create(&tid[i],NULL,tfn,(void*)i)) != 0)
这个tid变量没有进行初始化,就拿去使用了。注意内存的分配。


多线程编程,可能常常遇到内存问题。不过楼主的问题太基础了,还没等线程启动呢,您的程序就已经挂掉了。建议先把基础打牢,不然什么都是白搭。

我同意bruceteen的说法,多线程拷贝不会比单线程快。不过,如果一个线程用于拷贝文件,一个线程用于做其它工作,则总体效率有望得到提升,从而有望超过单线程的程序。如果使用异步IO,在仅使用单个线程的情况下也可以达到很高(或者说是最高?)的效率。

5 楼


非常感谢  我测试的时候把问题改好了。现在已经完成这个程序了。很高兴 ^_^  谢谢对菜鸟的支持了

我来回复

您尚未登录,请登录后再回复。点此登录或注册