`
jakielong
  • 浏览: 229172 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

给线程变量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);
            }
 
分享到:
评论

相关推荐

    linux_code.rar_linux 多线程_linux 线程_多线程编程

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); ``` 4. **线程同步**: - **互斥锁(Mutex)**:用于保护共享资源,确保任何时候只有一个线程...

    实验七:Linux多线程编程(实验报告).docx

    extern int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); ``` - `thread`:指向新创建线程ID的指针。 - `attr`:指定线程属性的结构体指针,可...

    pthread_self获取当前调用线程的识别码

    当你调用 `pthread_self()` 时,它会返回一个 `pthread_t` 类型的值,这个值可以用来区分系统中的不同线程,比如在需要同步或者互斥操作时。 在编写多线程程序时,`pthread_self` 的用途主要有以下几点: 1. **...

    linux的多线程编程的高效开发经验

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); ``` 2. **线程退出**:线程可以通过调用`pthread_exit()`函数来退出。当线程执行完其主函数...

    如何在linux进行线程编程

    使用`pthread_equal(pthread_t thread1, pthread_t thread2)`函数来判断两个线程标识符是否相同。 **5.3 仅执行一次的操作** `pthread_once()`函数确保某个函数只被执行一次,通常用于初始化操作。 ```c void ...

    Windows可使用的pthread库

    2. **线程同步**:pthread库提供了多种同步机制,包括互斥锁(`pthread_mutex_t`)、条件变量(`pthread_cond_t`)、信号量(`pthread_semaphore_t`)和读写锁(`pthread_rwlock_t`)。这些同步原语有助于防止数据...

    Linux系统编程-(pthread)线程创建与使用.zip

    `pthread_t`类型的变量用于存放新创建线程的ID,`start_routine`是线程启动函数,`arg`是传递给线程函数的参数。 - **pthread_exit**:用于终止线程执行,返回一个指针值。在多线程环境中,确保线程正确结束,应...

    C语言多线程

    - 函数原型: `int pthread_join(pthread_t thread, void **value_ptr);` - 参数说明: - `thread`: 等待退出的线程ID。 - `value_ptr`: 存储退出线程的返回值。 - **线程退出**: - 函数原型: `void pthread_...

    posix线程函数实例

    pthread_t thread1, thread2; pthread_mutex_init(&mutex, NULL); pthread_create(&thread1, NULL, increment_function, NULL); pthread_create(&thread2, NULL, increment_function, NULL); pthread_join...

    Linux下多线程编程-Pthread与Semaphore的使用.doc

    pthread_create 函数的原型为:extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr,void *(*__start_routine) (void *), void *__arg));第一个参数为指向线程标识符的指针,第二...

    pthread_doc

    `int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)` 与 fork() 调用创建一个进程的方法不同,pthread_create() 创建的线程并不具备与主线程(即调用 ...

    Linux多线程程序设计.ppt

    - `int pthread_create(pthread_t *thread, __const pthread_attr_t *attr, void *(*__start_routine) (void *), void *arg);`:创建一个新的线程,`thread`参数存储新线程的ID,`attr`指定线程属性,`start_...

    pthread_fab

    5. **线程同步**:在多线程环境中,可能会涉及到互斥锁(pthread_mutex_t)、条件变量(pthread_cond_t)等同步机制。这些机制用于控制对共享资源的访问,防止竞态条件,确保数据一致性。 6. **互斥锁(Mutex)**:...

    嵌入式\新——pthread_join_exit_演示.ppt

    当 `pthread_exit` 被调用时,它会清理当前线程的所有资源,包括栈空间、分配的内存等,并将控制权交还给父线程。如果其他线程正在等待这个线程(通过 `pthread_join`),那么 `retval` 将作为返回值传递给它们。 ...

    pthreads_pthread_

    5. `pthread_cond_t` 和 `pthread_cond_init() / pthread_cond_wait() / pthread_cond_signal() / pthread_cond_broadcast()`:条件变量,用于线程间通信和同步,当满足特定条件时,一个线程通知其他等待线程。...

    linuxC语言线程池实现CP命令

    pthread_t *tids;//线程id unsigned waiting_tasks;//等待任务 unsigned active_threads;// bool shutdown;//停始状态 }thread_pool; //初始化线程池 bool init_pool(thread_pool *pool, unsigned int ...

    test_pthread_kill测试程序_

    其中,`pthread_t thread`参数是目标线程的线程ID,`int sig`参数是要发送的信号。这个函数的作用是将`sig`信号发送给指定的线程`thread`。需要注意的是,尽管名称中含有"kill",但`pthread_kill`并不一定会立即结束...

Global site tag (gtag.js) - Google Analytics