zoukankan      html  css  js  c++  java
  • 给线程变量pthread_t *thread动态分配空间

    线程的创建和使用

    线程的创建是用下面的几个函数来实现的.

     

    #include <pthread.h>
                int pthread_create(pthread_t *thread,pthread_attr_t *attr,
                void *(*start_routine)(void *),void *arg);
                void pthread_exit(void *retval);
                int pthread_join(pthread *thread,void **thread_return);

     

    pthread_create创建一个线程,thread是用来表明创建线程的ID,attr指出线程创建时候的属性,我们用NULL来表明使用缺省属性.start_routine函数指针是线程创建成功后开始执行的函数,arg是这个函数的唯一一个参数.表明传递给start_routine的参数. pthread_exit函数和exit函数类似用来退出线程.这个函数结束线程,释放函数的资源,并在最后阻塞,直到其他线程使用pthread_join函数等待它.然后将*retval的值传递给**thread_return.由于这个函数释放所以的函数资源,所以retval不能够指向函数的局部变量. pthread_join和wait调用一样用来等待指定的线程. 下面我们使用一个实例来解释一下使用方法.在实践中,我们经常要备份一些文件.下面这个程序可以实现当前目录下的所有文件备份.备份后的后缀名为bak

     

    #include <stdio.h>
                #include <unistd.h>
                #include <stdlib.h>
                #include <string.h>
                #include <errno.h>
                #include <pthread.h>
                #include <dirent.h>
                #include <fcntl.h>
                #include <sys/types.h>
                #include <sys/stat.h>
                #include <sys/time.h>
                #define BUFFER 512
                struct copy_file {
                int infile;
                int outfile;
                };
                void *copy(void *arg)
                {
                int infile,outfile;
                int bytes_read,bytes_write,*bytes_copy_p;
                char buffer[BUFFER],*buffer_p;
                struct copy_file *file=(struct copy_file *)arg;
                infile=file->infile;
                outfile=file->outfile;
                /* 因为线程退出时,所有的变量空间都要被释放,所以我们只好自己分配内存了 */
                if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) pthread_exit(NULL);
                bytes_read=bytes_write=0;
                *bytes_copy_p=0;
                while((bytes_read=read(infile,buffer,BUFFER))!=0)
                {
                if((bytes_read==-1)&&(errno!=EINTR))break;
                else if(bytes_read>0)
                {
                buffer_p=buffer;
                while((bytes_write=write(outfile,buffer_p,bytes_read))!=0)
                {
                if((bytes_write==-1)&&(errno!=EINTR))break;
                else if(bytes_write==bytes_read)break;
                else if(bytes_write>0)
                {
                buffer_p+=bytes_write;
                bytes_read-=bytes_write;
                }
                }
                if(bytes_write==-1)break;
                *bytes_copy_p+=bytes_read;
                }
                }
                close(infile);
                close(outfile);
                pthread_exit(bytes_copy_p);
                }
                int main(int argc,char **argv)
                {
                pthread_t *thread;
                struct copy_file *file;
                int byte_copy,*byte_copy_p,num,i,j;
                char filename[BUFFER];
                struct dirent **namelist;
                struct stat filestat;
                /* 得到当前路径下面所有的文件(包含目录)的个数 */
                if((num=scandir(".",&namelist,0,alphasort))<0)
                {
                fprintf(stderr,"Get File Num Error:%s\n\a",strerror(errno));
                exit(1);
                }
                /* 给线程分配空间,其实没有必要这么多的 */
                if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)||
                ((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL)
                )
                {
                fprintf(stderr,"Out Of Memory!\n\a");
                exit(1);
                }
                for(i=0,j=0;i<num;i++)
                {
                memset(filename,'\0',BUFFER);
                strcpy(filename,namelist[i]->d_name);
                if(stat(filename,&filestat)==-1)
                {
                fprintf(stderr,"Get File Information:%s\n\a",strerror(errno));
                exit(1);
                }
                /* 我们忽略目录 */
                if(!S_ISREG(filestat.st_mode))continue;
                if((file[j].infile=open(filename,O_RDONLY))<0)
                {
                fprintf(stderr,"Open %s Error:%s\n\a",filename,strerror(errno));
                continue;
                }
                strcat(filename,".bak");
                if((file[j].outfile=open(filename,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))
                <0)
                {
                fprintf(stderr,"Creat %s Error:%s\n\a",filename,strerror(errno
                ));
                continue;
                }
                /* 创建线程,进行文件拷贝 */
                if(pthread_create(&thread[j],NULL,copy,(void *)&file[j])!=0)
                fprintf(stderr,"Create Thread[%d] Error:%s\n\a",i,strerror(errno));
                j++;
                }
                byte_copy=0;
                for(i=0;i<j;i++)
                {
                /* 等待线程结束 */
                if(pthread_join(thread[i],(void **)&byte_copy_p)!=0)
                fprintf(stderr,"Thread[%d] Join Error:%s\n\a",
                i,strerror(errno));
                else
                {
                if(bytes_copy_p==NULL)continue;
                printf("Thread[%d] Copy %d bytes\n\a",i,*byte_copy_p);
                byte_copy+=*byte_copy_p;
                /* 释放我们在copy函数里面创建的内存 */
                free(byte_copy_p);
                }
                }
                printf("Total Copy Bytes %d\n\a",byte_copy);
                free(thread);
                free(file);
                exit(0);
                }
  • 相关阅读:
    洛谷—— P2234 [HNOI2002]营业额统计
    BZOJ——3555: [Ctsc2014]企鹅QQ
    CodeVs——T 4919 线段树练习4
    python(35)- 异常处理
    August 29th 2016 Week 36th Monday
    August 28th 2016 Week 36th Sunday
    August 27th 2016 Week 35th Saturday
    August 26th 2016 Week 35th Friday
    August 25th 2016 Week 35th Thursday
    August 24th 2016 Week 35th Wednesday
  • 原文地址:https://www.cnblogs.com/cy163/p/1269921.html
Copyright © 2011-2022 走看看