IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [转]linux c++ 多线程编程

    cgl1079743846发表于 2016-04-23 11:36:27
    love 0

    文章参考: http://www.cnblogs.com/forstudy/archive/2012/04/05/2433853.html

    一. 进程和线程

         进程
         (1) 系统中程序执行和资源分配的基本单位
         (2) 每个进程有自己的数据段、代码段和堆栈段
         (3) 在进行切换时需要有比较复杂的上下文切换
     
         线程
         (1) 减少处理机的空转时间,支持多处理器以及减少上下文切换开销, 比创建进程小很多
         (2) 进程内独立的一条运行路线
         (3) 处理器调度的最小单元,也称为轻量级进程
         (4) 一个进程可以有多个线程,有多个线程控制表及堆栈寄存器,共享一个用户地址空间

    二. 线程函数
       1. 线程标识
           pthread_t pthread_self();
           返回值: 返回线程ID,linux规定为无符号长整数
       2. 线程相等
           int pthread_equal(pthread_t tid1, pthread_t tid2);
           返回值: 判断两个线程是否相等
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    int main(){
        pthread_t thread_id;
    
        thread_id=pthread_self(); // 返回调用线程的线程ID
        printf("Thread ID: %lu.\n",thread_id);
    
        if (pthread_equal(thread_id,pthread_self())) {
            if (thread_id==0) {
                printf("Equal!\n");
            } else {
                printf("Not equal!\n");
            }
            return 0;
        }
    }


        3. 创建线程
      int pthread_create(pthread_t *tid,const pthread_attr_t *attr,(void*)(*start_routine)(void*),void *arg);
      参数:
      1)tid, 线程标识符
      2)attr, 线程属性,通常设置为NULL
      3)start_routine, 线程函数
      4)arg, 传递给线程函数的参数
         返回值:
         1). 成功,返回0
         2). 失败,返回错误码
         说明:
         1). 线程创建完成之后,就开始从线程函数入口开始执行
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <iostream>
    
    void *thrd_func(void *arg);
    pthread_t tid;
    
    int main(){
        if (pthread_create(&tid,NULL,thrd_func,NULL)!=0) {
            printf("Create thread error!\n");
            exit(1);
        }
        sleep(1);  //sleep主线程,保证子线程能够执行成功
        printf("TID in pthread_create function: %lu.\n",tid);
        printf("Main process: PID: %d,TID: %lu.\n",getpid(), pthread_self()); 
        return 0;
    }
    
    void *thrd_func(void *arg){
        printf("I am new thread!\n");
        printf("New process:  PID: %d,TID: %lu.\n",getpid(), pthread_self());
        printf("New process:  PID: %d,TID: %lu.\n",getpid(), tid);
        pthread_exit(NULL);
        return 0;
    }

        4. 退出线程
           void pthread_exit(void* retVal);
           参数:
           1). retVal,线程结束的返回值,通常设置为NULL
           说明:
           1). 线程函数执行完毕之后当前线程也就退出了,如果使用thread_exit则是主动的退出线程
          
        5. 等待线程
           int pthread_join(pthread_t tid, void** retVal);
           参数:
           1. tid,线程标识符
           2. retVal,用来存储被等阻塞线程的返回值,通常设置为NULL
           返回值:
           1. 成功,返回0
           2. 失败,返回错误码
           说明:
           1. 这是一个线程阻塞函数,调用它的线程将会一直等待被阻塞的线程结束为止。函数返回时,被阻塞的线程资源被回收
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <iostream>
    
    void *thrd_func1(void *arg);
    void *thrd_func2(void *arg);
    
    int main(){
        pthread_t tid1,tid2;
        void *tret;
        // 创建线程tid1,线程函数thrd_func1
        if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) {
            printf("Create thread 1 error!\n");
            exit(1);
        }
        // 创建线程tid2,线程函数thrd_func2
        if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) {
            printf("Create thread 2 error!\n");
            exit(1);
        }
        // 主线程等待线程tid1结束
        int retCode = pthread_join(tid1, NULL);
        printf("Thread 1 exit code:%d\n", retCode);
        // 主线程等待线程tid2结束
        pthread_join(tid2, NULL);
        printf("Thread 2 exit code:%d\n", retCode);
        return 0;
    }
    
    void *thrd_func1(void *arg){
        printf("Thread 1 returning!\n");
        return ((void *)1); // 自动退出线程
    }
    
    void *thrd_func2(void *arg){
        printf("Thread 2 exiting!\n");
        pthread_exit((void *)2);  // 线程主动退出,返回(void *)2
    } 

    三. 线程同步与互斥
         线程共享进程的资源和地址空间,对这些资源进行操作时,必须考虑线程间同步与互斥问题
         三种线程同步机制
        •互斥锁
        •信号量
        •条件变量
         互斥锁更适合同时可用的资源是惟一的情况,信号量更适合同时可用的资源为多个的情况
        
        1. 互斥锁
      (1) 用简单的加锁方法控制对共享资源的原子操作,只有两种状态: 上锁、解锁
           (2) 可把互斥锁看作某种意义上的全局变量
      (3) 在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作
      (4) 若其他线程希望上锁一个已经被上锁的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止
    互斥锁保证让每个线程对共享资源按顺序进行原子操作
     
           互斥锁主要包括下面的基本函数:
      互斥锁初始化:pthread_mutex_init()
      互斥锁上锁:pthread_mutex_lock()
      互斥锁判断上锁:pthread_mutex_trylock()
      互斥锁解锁:pthread_mutex_unlock()
      消除互斥锁:pthread_mutex_destroy()
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <iostream>
    
    #define THREAD_NUM 3
    #define REPEAT_TIMES 5
    #define DELAY 4
    
    pthread_mutex_t mutex;
    
    void *thrd_func(void *arg);
    
    int main(){
        pthread_t thread[THREAD_NUM];
        int no;
        void *tret;
    
        srand((int)time(0));
       //初始化互斥锁  
       pthread_mutex_init(&mutex,NULL);
    
        for(no=0;no<THREAD_NUM;no++){
            if (pthread_create(&thread[no],NULL,thrd_func,(void*)no)!=0) {
                printf("Create thread %d error!\n",no);
                exit(1);
            }
            else {
                printf("Create thread %d success!\n",no);
        }
       //主线程等待子线程结束 
       for(no=0;no<THREAD_NUM;no++){
            if (pthread_join(thread[no],&tret)!=0){
                printf("Join thread %d error!\n",no);
                exit(1);
            }
            else {
                printf("Join thread %d success!\n",no);
            }
        }
        pthread_mutex_destroy(&mutex);
        return 0;
    }
    
    void *thrd_func(void *arg){
        int thrd_num=(int)arg;
        int delay_time,count; 
       //加锁
        if(pthread_mutex_lock(&mutex)!=0) {
            printf("Thread %d lock failed!\n",thrd_num);
            pthread_exit(NULL);
        }
    
        printf("Thread %d is starting.\n",thrd_num);
        for(count=0;count<REPEAT_TIMES;count++) {
            delay_time=(int)(DELAY*(rand()/(double)RAND_MAX))+1;
            sleep(delay_time);
            printf("\tThread %d:job %d delay =%d.\n",thrd_num,count,delay_time);
        }
    
        printf("Thread %d is exiting.\n",thrd_num);
        //解锁
       pthread_mutex_unlock(&mutex);
    
        pthread_exit(NULL);   
    }



沪ICP备19023445号-2号
友情链接