程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> 線程-求救高手。。linux c編程,用進程池實現shell命令cp

線程-求救高手。。linux c編程,用進程池實現shell命令cp

編輯:編程綜合問答
求救高手。。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;

}

最佳回答:


你試試 用 cp -r 遞歸復制那
-R
遞歸復制目錄,如果對象不是普通文件或目錄那麼做相應正確處理,(因此,一個 FIFO或者特殊文件在復制後仍然是一個 FIFO型或者相應特殊文件。)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved