zoukankan      html  css  js  c++  java
  • C/C++ 多线程机制

    一、C/C++多线程操作说明

    C/C++多线程基本操作如下: 
    1. 线程的建立结束 
    2. 线程的互斥和同步 
    3. 使用信号量控制线程 
    4. 线程的基本属性配置 

    在C/C++代码编写时,使用多线程机制,首先需要做的事情就是声明引用,具体如下:

    #include "pthread.h"

    二、线程基本操作方法

    基本线程操作:

    1. pthread_create():创建线程开始运行相关线程函数,运行结束则线程退出

    2. pthread_eixt():因为exit()是用来结束进程的,所以则需要使用特定结束线程的函数

    3. pthread_join():挂起当前线程,用于阻塞式地等待线程结束,如果线程已结束则立即返回,0=成功

    4. pthread_cancel():发送终止信号给thread线程,成功返回0,但是成功并不意味着thread会终止

    5. pthread_testcancel():在不包含取消点,但是又需要取消点的地方创建一个取消点,以便在一个没有包含取消点的执行代码线程中响应取消请求.

    6. pthread_setcancelstate():设置本线程对cancle线程的反应

    7. pthread_setcanceltype():设置取消状态 继续运行至下一个取消点再退出或者是立即执行取消动作

    8. pthread_setcancel():设置取消状态

    三、线程互斥与同步机制 

    基本的互斥与同步的操作方法:

    1. pthread_mutex_init():互斥锁的初始化

    2. pthread_mutex_lock():锁定互斥锁,如果尝试锁定已经被上锁的互斥锁则阻塞至可用为止

    3. pthread_mutex_trylock():非阻塞的锁定互斥锁

    4. pthread_mutex_unlock():释放互斥锁

    5. pthread_mutex_destory():互斥锁销毁函数

    四、多线程实践

    1. 基本的线程及建立运行

    下面的代码是C/C++开发的基本的线程的运行,使用的就是最基本的pthread.h:

    /* thread.c */
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
     
    #define THREAD_NUMBER       3                 /*线程数*/
    #define REPEAT_NUMBER       5                 /*每个线程中的小任务数*/
    #define DELAY_TIME_LEVELS  10.0             /*小任务之间的最大时间间隔*/
    //
    void *thrd_func(void *arg) { 
        /* 线程函数例程 */
        int thrd_num = (int)arg;
        int delay_time = 0;
        int count = 0;
        printf("Thread %d is starting
    ", thrd_num);
        for (count = 0; count < REPEAT_NUMBER; count++) {
            delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
            sleep(delay_time);
            printf("	Thread %d: job %d delay = %d
    ", thrd_num, count, delay_time);
        }
     
        printf("Thread %d finished
    ", thrd_num);
        pthread_exit(NULL);
    }
     
    int main(void) {
         pthread_t thread[THREAD_NUMBER];
         int no = 0, res;
         void * thrd_ret;
         srand(time(NULL));    
         for (no = 0; no < THREAD_NUMBER; no++) {
              /* 创建多线程 */
              res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
              if (res != 0) {
                   printf("Create thread %d failed
    ", no);
                   exit(res);
              }
         }
     
         printf("Create treads success
     Waiting for threads to finish...
    ");
         for (no = 0; no < THREAD_NUMBER; no++) {
              /* 等待线程结束 */
              res = pthread_join(thread[no], &thrd_ret);
              if (!res) {
                printf("Thread %d joined
    ", no);
              } else {
                printf("Thread %d join failed
    ", no);
              }
         }
         return 0;        
    }

    例程中循环3次建立3条线程,并且使用pthread_join函数依次等待线程结束; 
    线程中使用rand()获取随机值随机休眠5次,随意会出现后执行的线程先执行完成; 
    运行结果:

    $ gcc thread.c -lpthread
    $ ./a.out 
    Create treads success
     Waiting for threads to finish...
    Thread 0 is starting
    Thread 1 is starting
    Thread 2 is starting
    Thread 1: job 0 delay = 2
    Thread 1: job 1 delay = 2
    Thread 0: job 0 delay = 8
    Thread 2: job 0 delay = 10
    Thread 2: job 1 delay = 3
    Thread 1: job 2 delay = 10
    Thread 0: job 1 delay = 8
    Thread 0: job 2 delay = 3
    Thread 0: job 3 delay = 1
    Thread 2: job 2 delay = 8
    Thread 1: job 3 delay = 8
    Thread 1: job 4 delay = 1
    Thread 1 finished
            Thread 2: job 3 delay = 6
            Thread 0: job 4 delay = 7
    Thread 0 finished
    Thread 0 joined
    Thread 1 joined
            Thread 2: job 4 delay = 10
    Thread 2 finished
    Thread 2 joined

    可以看到,线程1先于线程0执行,但是pthread_join的调用时间顺序,先等待线程0执行; 
    由于线程1已经早结束,所以线程0被pthread_join等到的时候,线程1已结束,就在等待到线程1时,直接返回; 

    2. 线程执行的互斥和同步pthread_mutex_lock

    下面我们在上面的程序中增加互斥锁:

    /*thread_mutex.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <unistd.h>
     
    #define THREAD_NUMBER        3            /* 线程数 */
    #define REPEAT_NUMBER        3            /* 每个线程的小任务数 */
    #define DELAY_TIME_LEVELS 10.0         /*小任务之间的最大时间间隔*/
    pthread_mutex_t mutex;
     
    void *thrd_func(void *arg) {
         int thrd_num = (int)arg;
         int delay_time = 0, count = 0;
         int res;
         /* 互斥锁上锁 */
         res = pthread_mutex_lock(&mutex);
         if (res) {
              printf("Thread %d lock failed
    ", thrd_num);
              pthread_exit(NULL);
         }
         printf("Thread %d is starting
    ", thrd_num);
         for (count = 0; count < REPEAT_NUMBER; count++) {          
             delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
             sleep(delay_time);
             printf("	Thread %d: job %d delay = %d
    ", 
                                          thrd_num, count, delay_time);
         }
         printf("Thread %d finished
    ", thrd_num);
         /****互斥锁解锁***/
         pthread_mutex_unlock(&mutex);
         pthread_exit(NULL);
    }
     
    int main(void) {
         pthread_t thread[THREAD_NUMBER];
         int no = 0, res;
         void * thrd_ret;
     
         srand(time(NULL));
         /* 互斥锁初始化 */
         pthread_mutex_init(&mutex, NULL);
         for (no = 0; no < THREAD_NUMBER; no++) {
              res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
              if (res != 0) {
                  printf("Create thread %d failed
    ", no);
                  exit(res);
              }
         }     
         printf("Create treads success
     Waiting for threads to finish...
    ");
         for (no = 0; no < THREAD_NUMBER; no++) {
              res = pthread_join(thread[no], &thrd_ret);
              if (!res) {
                    printf("Thread %d joined
    ", no);
              } else  {
                  printf("Thread %d join failed
    ", no);
              }
         }   
         pthread_mutex_destroy(&mutex);          
         return 0;        
    }

    在上面的例程中直接添加同步锁pthread_mutex_t; 
    在线程中加入,程序在执行线程程序时,调用pthread_mutex_lock上锁,发现上锁时候后进入等待,等待锁再次释放后重新上锁; 
    所以线程程序加载到队列中等待,等待成功上锁后继续执行程序代码; 
    运行结果如下:

    Create treads success
     Waiting for threads to finish...
    Thread 0 is starting
        Thread 0: job 0 delay = 7
        Thread 0: job 1 delay = 2
        Thread 0: job 2 delay = 9
    Thread 0 finished
    Thread 2 is starting
    Thread 0 joined
        Thread 2: job 0 delay = 6
        Thread 2: job 1 delay = 7
        Thread 2: job 2 delay = 10
    Thread 2 finished
    Thread 1 is starting
        Thread 1: job 0 delay = 3
        Thread 1: job 1 delay = 5
        Thread 1: job 2 delay = 2
    Thread 1 finished
    Thread 1 joined
    Thread 2 joined 
  • 相关阅读:
    JS 和 CSS 的位置对其他资源加载顺序的影响
    How browsers workBehind the scenes of modern web browsers
    Gruntjs入门 (2)
    Superhero.js – 构建大型 JavaScript 应用程序的最佳资源
    利用位反操作来简化 indexOf 判断
    Gruntjs入门 (1)
    js和css的顺序关系
    (翻译)理解JavaScript函数调用和"this"(by Yehuda Katz)
    秒,微秒,毫秒
    您试图从目录中执行 CGI、ISAPI 或其他可执行程序,但该目录不允许执行程序
  • 原文地址:https://www.cnblogs.com/renhui/p/9900509.html
Copyright © 2011-2022 走看看