Linux多线程相关API演示

线程

程序运行后是进程,而线程寄生于进程之上,可以让一个进程中同时干不止一件事。进程有独立的地址空间,一个进程崩溃后,不会影响其他进程,而线程是寄托于进程之上一个进程死亡则整个线程死亡

线程特性

1. 节省空间,提升效率(人多干活快)
2. 方便通信(多个线程寄生于同一个进程,线程A变换数据,线程B可以立即知道)

线程相关API

pthread_create创建进程

  1. 原型
#include <pthread.h>

int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
  • pthread_t *restrict tidp —— 线程名
  • const pthread_attr_t *restrict attr —— 线程属性(NULL为默认)
  • void *(*start_rtn)(void *) —— 需要线程运行的代码
  • void *restrict arg —— 运行代码需要传入的参量(如有多个参数则放入到一个结构体中)
  1. 示例

创建一个进程打印一句话

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

void *func1(void *arg)
{
        printf("this is func1 print\n");
}
int main()
{
	pthread_t t1;
	ret = pthread_create(&t1,NULL,func1,(void *)&param);
	
	return 0;
}

pthread_join线程等待

  1. 原型
#include <pthread.h>

int pthread_join(pthread_t thread, void **rval_ptr);
  • pthread_t thread —— 线程名
  • void **rval_ptr —— 线程的返回值(不感兴趣设为NULL)
  1. 示例

等待线程结束后主进程才会结束,否则阻塞进程结束

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

void *func1(void *arg)
{
        printf("t1 %ld thread is create\n",(unsigned long)pthread_self());	//打印线程ID
        printf("t1 param is %d\n",*((int *)arg));		//打印传来的param值
}

int main()
{
        int ret;
        int param = 100;
        
        pthread_t t1;
        ret = pthread_create(&t1,NULL,func1,(void *)&param);
        
        if(ret == 0){		//判断是否创建成功
                printf("creat t1 success\n");
        }
        
        printf("main %ld \n",(unsigned long)pthread_self());
        
        pthread_join(t1,NULL);	//等待线程结束
        return 0;
}

pthread_exit线程退出

  1. 原型
#include <pthread.h>
int pthread_exit(void *rval_ptr);
  • void *rval_ptr —— 线程退出后返回给等待函数的值
  1. 示例

线程退出后将值传递回等待函数

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

void *func1(void *arg)
{
        static int ret = 10;		//必须为static类型否则传地址混乱
        pthread_exit((void *)&ret);
}

int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        
        int *pret = NULL;
        
        ret = pthread_create(&t1,NULL,func1,(void *)&param);	//创建进程
             
        pthread_join(t1,(void **)&pret);		//(void **)为pthread_join的格式
        printf("main: t1 quit:%d\n",*pret);
        return 0;
}

在多个线程同时运行时,无法保证线程A运行时线程B等待其运行结束后再运行,锁就发挥作用。

当线程A运行时可以上锁导致其他线程无法运行,只有线程A开锁后其他线程才可以开始抢夺运行权。

锁相关API

pthread_mutex_t mutex创锁
pthread_mutex_destroy消锁

  1. 原型
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t mutex);
  • pthread_mutex_t *restrict mutex —— 锁名
  • const pthread_mutexattr_t *restrict attr —— 默认量NULL即可
  1. 示例
    建立锁并且消锁
pthread_mutex_t mutex; 
pthread_mutex_init(&mutex,NULL);	//创锁
pthread_mutex_destroy(&mutex);  	//消锁

pthread_mutex_lock上锁
pthread_mutex_unlock解锁

  1. 原型
#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t mutex);
int pthread_mutex_unlock(pthread_mutex_t mutex);
  • pthread_mutex_t mutex —— 锁名
  1. 示例
    一旦有一线程抢先上锁后另外一线程将无法运行
#include<stdio.h>
#include<pthread.h>
#include <unistd.h>

pthread_mutex_t mutex;		//定义锁名

void *func1(void *arg)
{
        int i;
        pthread_mutex_lock(&mutex);	//上锁
        
        for(i=0;i<5;i++){
                printf("t1 param is %d\n",*((int *)arg));
        }
        
        pthread_mutex_unlock(&mutex);	//解锁
}

void *func2(void *arg)
{
        pthread_mutex_lock(&mutex);	//上锁
        
        printf("t2 param is %d\n",*((int *)arg));
        
        pthread_mutex_unlock(&mutex);	//解锁
}

int main()
{
        int ret;
        int param = 100;
        
        pthread_t t1;
        pthread_t t2;
        
        char *pret = NULL;
        
        pthread_mutex_init(&mutex,NULL);	//建锁
        
        ret = pthread_create(&t1,NULL,func1,(void *)&param);	//建立线程1
        ret = pthread_create(&t2,NULL,func2,(void *)&param);	//建立线程2
        
        pthread_join(t1,(void **)&pret);	//等待线程1结束
        pthread_join(t2,(void **)&pret);	//等待线程2结束
        
        pthread_mutex_destroy(&mutex);		//消锁
        return 0;
}

条件变量

使用锁后依旧无法控制线程的顺序问题,使用条件变量后可以调节其先后问题。

条件变量相关API

pthread_cond_init创建条件变量
pthread_cond_destroy删除条件变量

  1. 原型
#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t cond);
  • pthread_cond_t *restrict cond —— 条件变量名
  • const pthread_condattr_t *restrict attr —— 默认量NULL即可
  1. 示例
pthread_cond_t cond;

pthread_cond_init(&cond,NULL);
pthread_cond_destroy(&cond);

pthread_cond_wait等待
pthread_cond_signal触发

  1. 原型
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
  • pthread_cond_t *restrict cond —— 条件变量名
  • pthread_mutex_t *restrict mutex —— 锁名
#include <pthread.h>
int pthread_cond_signal(pthread_cond_t cond);
  • pthread_cond_t cond —— 条件变量名地址
  1. 示例
    进程2先运行当g_data加到3时触发信号,进程1运行并将g_data归零
#include<stdio.h>
#include<pthread.h>
#include <unistd.h>

int g_data = 0;
pthread_mutex_t mutex;		//定义锁名
pthread_cond_t cond;		//定义条件变量名

void *func1(void *arg)
{
        while(1){
                pthread_cond_wait(&cond,&mutex);	//等待触发
                
                printf("t1 run\n");
                
                printf("t1:%d\n",g_data);
                g_data = 0;
                sleep(1);
        }
}
void *func2(void *arg)
{
        while(1){
                printf("t2:%d\n",g_data);
                
                pthread_mutex_lock(&mutex);		//上锁
                g_data++;
                if(g_data == 3){
                 pthread_cond_signal(&cond);		//触发条件变量
                }
                
                pthread_mutex_unlock(&mutex);	//解锁
                sleep(1);
        }
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;
        
        char *pret = NULL;
        
        pthread_mutex_init(&mutex,NULL);		//创建锁
        pthread_cond_init(&cond,NULL);			//创建条件变量
        
        ret = pthread_create(&t1,NULL,func1,(void *)&param);	//建成进程1
        
        ret = pthread_create(&t2,NULL,func2,(void *)&param);	//建成进程2
        
        pthread_join(t1,(void **)&pret);	//等待进程1
        pthread_join(t2,(void **)&pret);	//等待进程2
        
        pthread_mutex_destroy(&mutex);		//消锁
        pthread_cond_destroy(&cond);		//删除条件变量
        return 0;
}

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页