链接: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\n",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\n", __LINE__, i);
pthread_mutex_lock(&mutex);/*锁住互斥量*/
printf("thread1: lock %d\n", __LINE__);
if(i%3==0)
{
printf("thread1:signal 1 %d\n", __LINE__);
pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/
printf("thread1:signal 2 %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n", __FUNCTION__, __LINE__);
sleep(1);
}
pthread_mutex_unlock(&mutex);/*解锁互斥量*/
printf("thread1: unlock %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n\n", __FUNCTION__, __LINE__);
sleep(1);
}
}

void *thread2(void *junk)
{
while(i<6)
{
printf("thread2: Line: %d, i = %d\n", __LINE__, i);
pthread_mutex_lock(&mutex);
printf("thread2: lock %d\n", __LINE__);
if(i%3!=0)
{
printf("thread2: wait 1 %d\n", __LINE__);
pthread_cond_wait(&cond,&mutex);/*解锁mutex,并等待cond改变*/
printf("thread2: wait 2 %d\n", __LINE__);
}
pthread_mutex_unlock(&mutex);
printf("thread2: unlock %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n\n", __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,并且解锁互斥量

[转]c++ pthread 多线程简介的更多相关文章

  1. pthread多线程编程的学习小结

    pthread多线程编程的学习小结  pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写     程序员必上的开发者服务平台 —— DevSt ...

  2. VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载

    VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程     转载 #include <stdio.h>#include &l ...

  3. iOS开发多线程篇—多线程简介

    iOS开发多线程篇-多线程简介 一.进程和线程 1.什么是进程 进程是指在系统中正在执行的一个应用程序 每一个进程之间是独立的.每一个进程均执行在其专用且受保护的内存空间内 比方同一时候打开QQ.Xc ...

  4. 多线程简介及GCD的使用

    多线程简介: 对于任意一个iOS应用,程序运行起来后,默认会产生一个主线程(MainThread),主线程专门用来处理UIKit对象的操作,如界面的显示与更新.处理用户事件触发的操作等等.(记忆这点, ...

  5. Java多线程简介

    Java多线程简介 Java中内置了对多线程的支持,让多线程的开发方便很多,但同时也带来了另外的复杂,线程间的交互以及很多的不确定性让多线程又显得很复杂.在此只是针对Java中多线程的基础做些说明,有 ...

  6. C语言使用pthread多线程编程(windows系统)二

    我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我 ...

  7. clone的fork与pthread_create创建线程有何不同&pthread多线程编程的学习小结(转)

    进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合,这些资源在Linux中被抽 象成各种数据对象:进程控制块.虚存空间.文件系统,文件I/O.信号处理函数.所以创建一个进程的 过程就是这 ...

  8. NDK中使用pthread多线程中自己写的一个BUG

    在使用pthread进行NDK中的多线程开发时,自己写了一个BUG, void *darkGrayThread(void *args) { ThreadParam *param = (ThreadPa ...

  9. php Pthread 多线程基本介绍

    我们可以通过安装Pthread扩展来让PHP支持多线程.   线程,有时称为轻量级进程,是程序执行的最小单元.线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,它与同属 ...

随机推荐

  1. Python学习日记(二十九) 网络编程

    早期的计算机通信需要有一个中间件,A要给B传东西,A必须要把信息传给中间件,B再把从中间件中拿到信息 由于不同机器之间需要通信就产生了网络 软件开发的架构 1.C/S架构 服务器-客户机,即Clien ...

  2. Flask--登录验证(多个装饰器)

    登录验证(多个装饰器) from flask import Flask,url_for,session,render_template import functools app = Flask(__n ...

  3. restTemplate x-www-form-urlencoded

    MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();postParameter ...

  4. 转:MySQL到底能支持多大的数据量?

    MySQL到底能支持多大的数据量? MySQL是中小型网站普遍使用的数据库之一,然而,很多人并不清楚MySQL到底能支持多大的数据量,再加上某些国内CMS厂商把数据承载量的责任推给它,导致很多不了解M ...

  5. 2、Python的IDE之PyCharm的使用

    一.Python集成开发环境-Pycharm介绍 PyCharm是一款功能强大的,用于编写复杂需要结构化的功能代码,下面介绍一下 在Windows下如何安装PyCharm . 操作系统:Windows ...

  6. PAT1057 stack(分块思想)

    1057 Stack (30分)   Stack is one of the most fundamental data structures, which is based on the princ ...

  7. LeetCode 1011. Capacity To Ship Packages Within D Days

    原题链接在这里:https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/ 题目: A conveyor belt h ...

  8. LeetCode 1140. Stone Game II

    原题链接在这里:https://leetcode.com/problems/stone-game-ii/ 题目: Alex and Lee continue their games with pile ...

  9. JavaScript基础03——函数的作用域及变量提升

    1.作用域 作用域,变量在函数内部作用的范围/区域.有函数的地方就有作用域.   2.局部作用域和全局作用域 function fn(){ var a = 1; } console.log(a); / ...

  10. A simple dispiction of dijkstra

    前言 \(SPFA\)算法由于它上限 \(O(NM) = O(VE)\)的时间复杂度,被卡掉的几率很大.在算法竞赛中,我们需要一个更稳定的算法:\(dijkstra\). 什么是\(dijkstra\ ...