Chinaunix首页 | 论坛 | 博客
  • 博客访问: 47511
  • 博文数量: 20
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 145
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-16 15:07
文章分类

全部博文(20)

文章存档

2010年(15)

2008年(5)

我的朋友

分类: C/C++

2008-11-14 10:17:09

  线程的创建者在创建线程时可能会用指向void的指针向线程传递单个参数。要传
 
递多个值的话,创建者就必须使用指向数组或结构的指针。下面的代码说明了如何传
 
递一个指向数组的指针。main函数将包含两个打开的文件描述符的数组传递给一个
 
运行copyfilemalloc的线程
 
 

程序1-----------------------------------------------callcopymalloc.c

创建了一个线程来拷贝文件的程序

#include<errno.h>
#include<fcntl.h>
#include<pthread.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#define PERMS (S_IRUSR | S_IWUSR)
#define TRAD_FLAGS O_RDONLY
#define WRITE_FLAGS(O_WRONLY | O_CREAT | O_TRUNC)

void *copyfilemalloc(void * arg);

int main(int argc, char *argv[])
{
        int *bytesptr;
        int error;
        int fds[2];
        pthread_t tid;
        
        if(argc!=3)
        {
                fprintf(stderr,"Usage:%s fromfile tofile\n",argv[0]);
                return 1;
        
        }    
        if(((fds[0] = open(argv[1],READ_FLAGS))==-1)||((fds[1] = open(argv[2],WRITE_FLAGS,PERMS))==-1))
        {
                    perror("Failed to open the files");
                    return 1;
        }
        if(error = pthread_create(&tid,NULL,copyfilemalloc,fds))
        {
                fprintf(stderr."Failed to create thread :%s\n",strerror(error));    
                return 1;
        }
        if(error = pthread_join(tid,(void **)&bytesptr))
        {
                fprintf(stderr,"Failed to join thread: %s\n",strerror(error));
                return 1;    
        }
        printf("Number of bytes copied: %d\n",*bytesptr);
        return 0;
}

 

    程序5显示的是copyfilemalloc的实现,这个函数从一个文件中读入并向另一个文件中

输出。参数arg中装载了一个指针,这个指针指向一对用来表示源和目标文件的打开的文件描

述符。变量bytesp、infd和outfd是在copyfilemalloc的局部栈上分配的,不能被其他线程

直接访问。

    程序5还说明了从线程中返回值的策略。因为不允许线程返回一个指向它的局部变量的指

针,所以线程为返回拷贝的字节总数分配了内存空间。POSIX要求malloc是线程安全的。

copyfilemalloc函数返回bytesp指针,这和调用pthread_exit的效果是一样的。使用完之

后释放这个空间是调用程序(callcopymalloc)的责任。在这种情况下,程序会终止,因此

就不需要调用free了

 

程序2-----------------------------------------------copyfilemalloc.c
copyfilemalloc函数通过调用copyfile函数将一个文件的内容拷贝到另一个文件中去。它通过为返回值动态的分配空间来返回拷贝的字节数

 
#include<stdlib.h>
#include<unistd.h>
#include"restart.h"
#define BLKSIZE 1024

int copyfile(int fromfd,int tofd)
{
        char buf[BLKSIZE];
        int bytesread,byteswritten;
        int totalbytes = 0;
        for( ; ; )
        {
               if((bytesread = r_read(fromfd,buf,BLKSIZE))<=0)
               {
                            break; 
               }
               if((byteswritten = r_write(tofd,buf,bytesread))==-1)
               {
                            break; 
               }
               totalbytes +=byteswritten;
        }
        return totalbytes;
}


void *copyfilemalloc(void *arg)
{
        int *bytesp;
        int infd;
        int outfd;
        
        infd = *((int *)(arg));
        outfd = *((int *)(arg)+1);
        if((bytesp = (int *)malloc(sizeof(int))) == NULL)
        {
                return NULL;
        }
        *bytesp = copyfile(infd,outfd);
        r_close(infd);
        r_close(outfd);
        return bytesp;
}

 

    当线程为返回值分配空间时,其他的一些线程要负责释放那个空间。只要可能,在任何情

况下,线程都应该自己来处理自己的事情,而不应该要求另一个线程来处理。动态分配空间来

装载单个整数的效率也是很低的。另一种用线程为返回值分配空间的方法是由创建线程来完成

这项工作,并在线程的参数中传递一个指向这个空间的指针。   

 

程序3--------------------------------------------------------callcopypass.c
程序创建了一个线程来拷贝文件。线程的参数是一个由三个整数组成的数组,这三个参数用来表示两个文件描述符和拷贝的字节数。

#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#define PERMS (S_IRUSR | S_IWUSR)
#define READ_FLAGS O_RDONLY
#define WRITE_FLAGS (O_WRONLY | O_CREAT | O_TRUNC)
void *copyfilepass(void *arg);

int main (int argc, char *argv[]) {
   int *bytesptr;
   int error;
   int targs[3];
   pthread_t tid;

   if (argc != 3) {
      fprintf(stderr, "Usage: %s fromfile tofile\n", argv[0]);
      return 1;
   }

   if (((targs[0] = open(argv[1], READ_FLAGS)) == -1) ||
       ((targs[1] = open(argv[2], WRITE_FLAGS, PERMS)) == -1)) {
      perror("Failed to open the files");
      return 1;
   }
   if (error = pthread_create(&tid, NULL, copyfilepass, targs)) {
      fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
      return 1;
   }
   if (error = pthread_join(tid, (void **)&bytesptr)) {
      fprintf(stderr, "Failed to join thread: %s\n", strerror(error));
      return 1;
   }
   printf("Number of bytes copied: %d\n", *bytesptr);
   return 0;
}

 

 

程序4--------------------------------------------------------copyfilepass.c
可被callcopypass用来拷贝文件的线程

#include <unistd.h>
#include "restart.h"

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;
}

    callcopypass可以用args[2]来访问拷贝的字节数,为什么还要让copyfilepass返回一个指向这个值的指针?

    如果一个创建线程之外的其他线程与copyfilepass结合起来,它就可以通过pthread_join的参数来访问拷贝的字节数了。

 

 

 

 

阅读(1604) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~