zoukankan      html  css  js  c++  java
  • [转]c++ pthread 多线程简介

    链接:https://blog.csdn.net/u013894427/article/details/83827173

    pthread 入口函数类型说明
    void * func1(void * t)
    void* 表示无类型指针

    void*作为函数参数,表示函数接收一个指针,不管是什么类型的指针都可以,但是传递之前要强制转换为无类型指针。

    基础流程
    pthread_t t1;//声明一个线程
    pthread_create(&t1, NULL, &test, (void *)this);//创建一个线程
    pthread_exit(NULL);//退出线程

    pthread_create()

    函数原型

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    void *(*start_routine) (void *), void *arg);
    含有四个参数,

    第一个参数表示线程id
    第二个参数表示线程参数
    第三个是线程的入口函数名字
    第四个参数表示线程入口函数的参数名字


    pthread_exit();

    函数原型

    void pthread_exit(void *retval)


    写在线程内部,用于强制退出当前线程

    如果线程是joinable,可以在函数参数里面传递线程的退出信息给主线程

    例如

    #include <pthread.h>
    #include <iostream>

    using namespace std;

    void *thread1(void *);
    int status;
    int main(void)
    {
    void *status_m;
    cout << "status_m addr is " << &status_m << endl;
    pthread_t t_a;
    pthread_create(&t_a,NULL,thread1,NULL);/*创建进程t_a*/
    pthread_join(t_a, &status_m);/*等待进程t_a结束*/
    cout << "status_m value is " << status_m << endl;
    int * re=(int *)status_m;
    cout << "the value is " << *re << endl;
    return 0;
    }
    void *thread1(void *junk)
    {
    status=23333;
    cout << "status addr is " << &status << endl;
    pthread_exit((void *)&status);
    }

    可以打印出

    status_m addr is 0x7ffe3cfd6170
    status addr is 0x6021b4
    status_m value is 0x6021b4
    the value is 23333
    线程的joinable和detached属性
    属性的设置方法如下

    pthread_attr_t attr;//声明一个参数
    pthread_attr_init(&attr);//对参数进行初始化
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);//设置线程为可连接的
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//设置线程为可分离的
    pthread_attr_destroy(&attr)//销毁属性,防止内存泄漏
    属性的相关操作如下:

    pthread_detach()

    函数原型

    int pthread_detach(pthread_t tid);
    1
    detached的线程在结束的时候会自动释放线程所占用的资源

    pthread_join()

    函数原型

    int pthread_join(pthread_t tid, void **status);

    joinable的线程必须用pthread_join()函数来释放线程所占用的资源,如果没有执行这个函数,那么线程的资源永远得不到释放。

    互斥锁 mutex
    互斥锁是为了多个线程在运行过程中保持数据同步引入的机制。

    基本流程

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
    pthread_mutex_init(&mutex,NULL);/*动态初始化互斥锁*/
    pthread_mutex_lock(&mutex);//加锁
    pthread_mutex_unlock(&mutex);//解锁
    pthread_mutex_destroy(&mutex);//销毁互斥锁
    举个例子

    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>

    pthread_mutex_t mutex ;
    void *print_msg(void *arg){
    int i=0;
    pthread_mutex_lock(&mutex);
    for(i=0;i<15;i++){
    printf("output : %d ",i);
    usleep(100);
    }
    pthread_mutex_unlock(&mutex);
    }
    int main(int argc,char** argv){
    pthread_t id1;
    pthread_t id2;
    pthread_mutex_init(&mutex,NULL);
    pthread_create(&id1,NULL,print_msg,NULL);
    pthread_create(&id2,NULL,print_msg,NULL);
    pthread_join(id1,NULL);
    pthread_join(id2,NULL);
    pthread_mutex_destroy(&mutex);
    return 1;
    }
    条件变量
    基本流程

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/
    pthread_mutex_lock(&mutex);/*锁住互斥量*/
    pthread_cond_signal(&cond);//发送信号量 跟wait函数不在同一个线程中
    pthread_cond_wait(&cond,&mutex);//阻塞线程,等待条件变量,同时解锁互斥量
    pthread_mutex_unlock(&mutex);//解锁互斥量
    pthread_mutex_destroy(&mutex);//销毁互斥锁
    pthread_cond_destroy(&cond);//销毁条件变量
    举个例子

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/

    void *thread1(void *);
    void *thread2(void *);

    int i=1;

    int main(void)
    {
    pthread_t t_a;
    pthread_t t_b;
    pthread_create(&t_a,NULL,thread1,(void *)NULL);/*创建进程t_a*/
    pthread_create(&t_b,NULL,thread2,(void *)NULL); /*创建进程t_b*/
    pthread_join(t_a, NULL);/*等待进程t_a结束*/
    pthread_join(t_b, NULL);/*等待进程t_b结束*/
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    exit(0);
    }
    void *thread1(void *junk)
    {
    for(i=1;i<=6;i++)
    {
    printf("thread1: Line: %d, i = %d ", __LINE__, i);
    pthread_mutex_lock(&mutex);/*锁住互斥量*/
    printf("thread1: lock %d ", __LINE__);
    if(i%3==0)
    {
    printf("thread1:signal 1 %d ", __LINE__);
    pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/
    printf("thread1:signal 2 %d ", __LINE__);
    printf("%s will sleep 1s in Line: %d ", __FUNCTION__, __LINE__);
    sleep(1);
    }
    pthread_mutex_unlock(&mutex);/*解锁互斥量*/
    printf("thread1: unlock %d ", __LINE__);
    printf("%s will sleep 1s in Line: %d ", __FUNCTION__, __LINE__);
    sleep(1);
    }
    }


    void *thread2(void *junk)
    {
    while(i<6)
    {
    printf("thread2: Line: %d, i = %d ", __LINE__, i);
    pthread_mutex_lock(&mutex);
    printf("thread2: lock %d ", __LINE__);
    if(i%3!=0)
    {
    printf("thread2: wait 1 %d ", __LINE__);
    pthread_cond_wait(&cond,&mutex);/*解锁mutex,并等待cond改变*/
    printf("thread2: wait 2 %d ", __LINE__);
    }
    pthread_mutex_unlock(&mutex);
    printf("thread2: unlock %d ", __LINE__);
    printf("%s will sleep 1s in Line: %d ", __FUNCTION__, __LINE__);
    sleep(1);
    }
    }
    结果为:

    thread1: Line: 29, i = 1
    thread1: lock 31
    thread1: unlock 41
    thread1 will sleep 1s in Line: 42

    thread2: Line: 52, i = 1
    thread2: lock 54
    thread2: wait 1 57
    thread1: Line: 29, i = 2
    thread1: lock 31
    thread1: unlock 41
    thread1 will sleep 1s in Line: 42

    thread1: Line: 29, i = 3
    thread1: lock 31
    thread1:signal 1 34
    thread1:signal 2 36
    thread1 will sleep 1s in Line: 37
    thread1: unlock 41
    thread1 will sleep 1s in Line: 42

    thread2: wait 2 59
    thread2: unlock 62
    thread2 will sleep 1s in Line: 63

    thread1: Line: 29, i = 4
    thread1: lock 31
    thread1: unlock 41
    thread1 will sleep 1s in Line: 42

    thread2: Line: 52, i = 4
    thread2: lock 54
    thread2: wait 1 57
    thread1: Line: 29, i = 5
    thread1: lock 31
    thread1: unlock 41
    thread1 will sleep 1s in Line: 42

    thread1: Line: 29, i = 6
    thread1: lock 31
    thread1:signal 1 34
    thread1:signal 2 36
    thread1 will sleep 1s in Line: 37
    thread1: unlock 41
    thread2: wait 2 59
    thread2: unlock 62
    thread2 will sleep 1s in Line: 63

    thread1 will sleep 1s in Line: 42
    注意:thread2 wait 1和thread2 wait 2的位置可以知道wait函数在执行的时候会阻塞thread2,并且解锁互斥量

  • 相关阅读:
    POJ 2112 Optimal Milking (Dinic + Floyd + 二分)
    POJ 3678 Katu Puzzle (2-SAT)
    超详细的Java面试题总结(一)之Java基础知识篇
    Java高级面试题及答案
    Java线程面试题 Top 50
    Java面试题收集
    Spring基础使用(一)--------IOC、Bean的XML方式装配
    你不知道的Javascript:有趣的setTimeout
    Java 10 的 10 个新特性,将彻底改变你写代码的方式!
    深入理解 Java 多线程核心知识:跳槽面试必备
  • 原文地址:https://www.cnblogs.com/lyggqm/p/11451855.html
Copyright © 2011-2022 走看看