线程的创建者在创建线程时可能会用指向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) |