2 u011285271 u011285271 于 2013.07.02 23:06 提问

求救高手。。linux c编程,用进程池实现shell命令cp

现在状态是,复制单个文件没问题,复制一个目录且目录里没有子目录也没问题。

如果目录里有一个子目录,这样貌似没有问题,但是如果有多个子目录,就会出现各种问题。

弄了一个晚上了,各种惆怅,求救各位老大帮忙看看。

本人新手,代码比较乱真的非常抱歉。

//code start
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define SIZE 500

struct copy_info //arg of task function
{
char srcdir[SIZE];
char tardir[SIZE];
char srcname[SIZE];
char tarname[SIZE];
};

struct task //task list node
{
void (*job)(struct copy_info);
struct copy_info arg;

struct task *next;

};

struct thread_pool //thread pool
{
pthread_mutex_t m;
sem_t s;

struct task *head;

pthread_t *tids;

unsigned thread_num;
unsigned task_num;

};

static struct thread_pool *pool;
char dir[50];

#if 1
void *routine(void *arg) //thread function
{
while(1){
printf("pthread routine\n");
// waiting for a task to run
sem_wait(&pool->s);

    // lock task queue, and consume the task
    pthread_mutex_lock(&pool->m);

    struct task *p = pool->head->next;
    pool->head->next = p->next;

    pthread_mutex_unlock(&pool->m);

    // execute the job
    (p->job)(p->arg);
    pool->task_num--;
    free(p);
    p = NULL;
}

}
#endif

#if 1
void pool_init(int thread_num)
{
pool = (struct thread_pool *)malloc(sizeof(struct thread_pool));

pthread_mutex_init(&pool->m, NULL);
sem_init(&pool->s, 0, 0);

struct task *p = (struct task *)malloc(sizeof(struct task));
p->next = NULL;
pool->head = p;

pool->tids = (pthread_t *)malloc(sizeof(pthread_t) * thread_num);

pool->thread_num = thread_num;
pool->task_num = 0;

int i;
for(i=0; i<thread_num; i++)
    pthread_create(pool->tids+i, NULL, routine, NULL);

}
#endif

void add_task(void (*job)(struct copy_info), struct copy_info arg)
{
while(pool->task_num >= 10);

struct task *newtask = (struct task *)malloc(sizeof(struct task));
newtask->job = job;
newtask->arg = arg;
newtask->next = NULL;

pthread_mutex_lock(&pool->m);

struct task *p = pool->head;
while(p->next != NULL)
    p = p->next;

p->next = newtask;

pool->task_num++;

pthread_mutex_unlock(&pool->m);

sem_post(&pool->s);

}

void copy_file(struct copy_info info) //task function
{
int fd1, fd2;
ssize_t m, n;
char buf[1000];
char *p;

#ifdef DEBUG
printf("tid = %u\n", (unsigned)pthread_self());
printf("srcdir = %s, srcfile = %s\n", info.srcdir, info.srcname);
printf("tardir = %s, tarfile = %s\n", info.tardir, info.tarname);
#endif

chdir(info.srcdir);
fd1 = open(info.srcname, O_RDONLY);
if(fd1 == -1)
{
    perror("open file");
    exit(1);
}
chdir(info.tardir);
fd2 = open(info.tarname, O_RDWR | O_CREAT, 0777);
if(fd2 == -1)
{
    perror("open file");
    exit(1);
}

while(1)
{

// chdir(info.srcdir);

    n = read(fd1, buf, 1000);
    if(n == -1)
    {
        perror("read file");
        exit(1);
    }
    else if(!n)
        break;

    m = 0;
    p = buf;

// chdir(info.tardir);
while(n)
{
n = n - m;
p = p + m;
m = write(fd2, p, n);
if(m == -1)
{
perror("write file");
exit(1);
}
}
}
close(fd1);
close(fd2);
}

void copy_dir(char *src, char *tar)
{
int i;

char newsrc[SIZE];
char newtar[SIZE];
char newname[SIZE];
char sysstr[SIZE];

memset(newsrc, 0, SIZE);
memset(newtar, 0, SIZE);
memset(sysstr, 0, SIZE);
memset(newname, 0, SIZE);

strcpy(newsrc, src);
strcpy(newtar, tar);

// sprintf(sysstr, "mkdir %s\n", newtar);
// system(sysstr);
mkdir(newtar, 0777);

DIR *dp;

// chdir(newsrc);
// chdir("..");
dp = opendir(newsrc);
chdir(newsrc);
// get_current_dir_name();

struct copy_info info;
memset(info.srcdir, 0, SIZE);
memset(info.tardir, 0, SIZE);
memset(info.srcname, 0, SIZE);
memset(info.tarname, 0, SIZE);

struct dirent *ep;
while(1)
{
    strcpy(newsrc, src);
    strcpy(newtar, tar);

    ep = readdir(dp);
    if(ep == NULL)
        break;

    if(ep->d_name[0] == '.')
        continue;

    struct stat buf;
    strcpy(newname, newsrc);
    for(i=0; newname[i]!='\0'; i++);
    if(newname[i-1] != '/')
        strcat(newsrc, "/");
    strcat(newname, ep->d_name);

    lstat(newname, &buf);
    if(S_ISDIR(buf.st_mode))
    {
        for(i=0; newsrc[i]!='\0'; i++);
        if(newsrc[i-1] != '/')
            strcat(newsrc, "/");
        strcat(newsrc, ep->d_name);


        for(i=0; newtar[i]!='\0'; i++);
        if(newtar[i-1] != '/')
            strcat(newtar, "/");
        strcat(newtar, ep->d_name);

        copy_dir(newsrc, newtar);
    }
    else
    {
        strcpy(info.srcdir, newsrc);
        strcpy(info.tardir, newtar);
        strcpy(info.srcname, ep->d_name);
        strcpy(info.tarname, ep->d_name);

        add_task(copy_file, info);
    }
}

}

void getinfo(struct copy_info *info, char *src, char *tar)
{
int i, j;
for(i=0; src[i]!='\0' && src[i]!='/'; i++);
if(src[i] == '/')
{
for(; src[i]!='\0'; i++);
for(j=i; src[j]!='/'; j--);
for(i=0; i info->srcdir[i] = src[i];

    for(i=j+1; src[i]!='\0'; i++)
        info->srcname[i-j-1] = src[i];
}
else
{
    strcpy(info->srcdir, ".");
    strcpy(info->srcname, src);
}

for(i=0; tar[i]!='\0' && tar[i]!='/'; i++);
if(tar[i] == '/')
{
    for(; tar[i]!='\0'; i++);
    for(j=i; tar[j]!='/'; j--);
    for(i=0; i<j; i++)
        info->tardir[i] = tar[i];

    for(i=j+1; tar[i]!='\0'; i++)
        info->tarname[i-j-1] = tar[i];
}
else
{
    strcpy(info->tardir, ".");
    strcpy(info->tarname, tar);
}

}

int main(int argc, char *argv[])
{
umask(0);

char src[SIZE] = "/mnt/hgfs/share/1st/data_struct/";
char tar[SIZE] = "/home/william/2code/";

#if 0
strcpy(src, argv[1]);
strcpy(tar, argv[2]);

if(argc != 3)
{
    printf("arguments not match.\n");
    exit(1);
}

#endif

pool_init(3);
printf("init finished\n");

int fd = open(src, O_RDONLY);
if(fd == -1)
{
    printf("can not find file.\n");
    exit(1);
}

struct stat buf;
if(fstat(fd, &buf) == -1)
{
    printf("read stat fail.\n");
    exit(1);
}
close(fd);

if(S_ISDIR(buf.st_mode))
    copy_dir(src, tar);
else
{
    struct copy_info info;
    memset(info.srcdir, 0, SIZE);
    memset(info.tardir, 0, SIZE);
    memset(info.srcname, 0, SIZE);
    memset(info.tarname, 0, SIZE);
    getinfo(&info, src, tar);
    add_task(copy_file, info);
}

pause();

return 0;

}

1个回答

u012562712
u012562712   2013.12.13 12:43
已采纳

你试试 用 cp -r 递归复制那
-R
递归复制目录,如果对象不是普通文件或目录那么做相应正确处理,(因此,一个 FIFO或者特殊文件在复制后仍然是一个 FIFO型或者相应特殊文件。)

Csdn user default icon
上传中...
上传图片
插入图片