线程的函数及使用

108 阅读4分钟

4月「掘金·日新计划」第9天

一、相关函数

进程函数包含3点:线程,互斥锁,条件

二、实践使用

pthread库,编译-pthread

2.1、线程pthread_create,pthread_exit,pthread_join,pthread_self,pthread_equal

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

功能:创建线程

参数:

  1. pthread_t指针t1
  2. 线程属性,NULL
  3. 函数指针,线程执行的函数
  4. 传递数据,无类型数据(可以传结构体数据)

返回值:成功0,错误错误编号

void pthread_exit(void *retval);

功能:退出线程

参数:无类型指针,线程退出传的数据,要保证内存不释放,static关键字

int pthread_join(pthread_t thread, void **retval);

功能:等待,主函数阻塞等待线程退出

参数:

  1. t1
  2. 退出返回值,二级指针,就是退出函数的参数
pthread_t pthread_self(void);

功能:返回线程id

返回值:长整形,%ld

int pthread_equal(pthread_t t1, pthread_t t2);

功能:id比较

返回值:相等非0,否则0

例子:

  1. 创建线程
  2. 编写线程函数,输出主函数的值(结构体指针数组)和线程id,退出返回一个数据
  3. 主函数,输出id,等待线程,输出线程退出的数
  4. 注:编译加-lpthread
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct Student{
        int arg;
        char name[12];
        struct Student *next;
}student;
​
//线程执行函数
void *fun1(void *ar)    
{
        static char *ptr = "wei"; //返回数据,要static防止释放
        student **p = (student **)ar;   //要用二级指针,因为数组里面还是地址
        printf("t1:arg1=%d\n",p[0]->arg); //打印,结构体里的内容
//      student *p = *(student **)ar;
//      printf("t1:arg1=%d\n", p->arg);
        printf("t1:name1=%s\n",p[0]->name);
        printf("t1:arg2=%d\n",p[1]->arg);
        printf("t1:name2=%s\n",p[1]->name);
        printf("t1:id=%ld\n",(unsigned long)pthread_self());    //打印id
        pthread_exit((void *)ptr);      //退出线程,返回ptr数据
}
​
int main()
{
        pthread_t t1;
        student s1={21,"xiao"}; //定义2个结构体变量
        student s2={30,"wei"};
        student *array[2]={&s1, &s2};   //放入结构体指针数组
        int arg = 100;         //
        char *a = NULL; //线程退出,数据接收指针
​
        if(pthread_create(&t1, NULL, fun1, (void *)array) == 0){    //创建线程,传入指针数组
                printf("found thread succeed\n");
        }
​
        printf("main:id=%ld\n",(unsigned long)pthread_self());  //打印id
​
        pthread_join(t1, (void **)&a);  //等待线程退出,阻塞
        printf("main:t1 exit,%s\n",(char*)a);   //打印线程退出返回的数据
        return 0;
}
​
/*
found thread succeed
main:id=139959759869760
t1:arg1=21
t1:name1=xiao
t1:arg2=30
t1:name2=wei
t1:id=139959759865600
main:t1 exit,wei
*/

2.2、互斥锁pthread_mutex_init,pthread_mutex_destroy,pthread_mutex_lock,pthread_mutex_unlock

int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr)

功能:创建锁

参数:

  1. 全局变量,指针
  2. 属性,NULL
int pthread_mutex_destroy(pthread_mutex_t *mutex)

功能:销毁锁

参数:全局变量,指针

int pthread_mutex_lock(pthread_mutex_t *mutex)

功能:加锁

参数:全局变量,指针

int pthread_mutex_unlock(pthread_mutex_t *mutex)

功能:解锁

参数:全局变量,指针

例子:

  1. 全局变量data和锁变量

  2. 创建锁,创建2个线程

  3. 2线程函数

  4. 1: 加锁,循环data++,sleep延时1s,if3解锁退出线程

  5. 2:死循环输出data,加锁data++,解锁,延时1s

  6. 主函数,打印data,等待线程

  7. 销毁锁

    注:线程2加锁是因为锁被线程1拿了,没有锁拿就会卡在那里。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
​
int data = 0;
pthread_mutex_t nutex;
​
void *fun1(void *arg)
{
        printf("t1:id=%ld\n",(unsigned long)pthread_self());
        pthread_mutex_lock(&nutex);
        while(1){
                data++;
                printf("t1:data=%d\n",data);
                if(data == 3){
                        printf("t1 quit =============================\n");
                        pthread_mutex_unlock(&nutex);
                        pthread_exit(NULL);
                }
                sleep(1);
        }
}
​
void *fun2(void *arg)
{
        printf("t2:id=%ld\n",(unsigned long)pthread_self());
        while(1){
                pthread_mutex_lock(&nutex);
                data++;
                pthread_mutex_unlock(&nutex);
                printf("t2:data=%d\n",data);
                sleep(1);
        }
        pthread_exit(NULL);
}
​
int main()
{
        pthread_t t1;
        pthread_t t2;
        int arg = 100;
        pthread_mutex_init(&nutex, NULL);
        if(pthread_create(&t1, NULL, fun1, (void *)&arg) == 0){
                printf("found thread succeed\n");
        }
​
        if(pthread_create(&t2, NULL, fun2, (void *)&arg) == 0){
                printf("found thread succeed\n");
        }
        printf("main:id=%ld\n",(unsigned long)pthread_self());
        while(1){
                printf("main:%d\n",data);
                sleep(1);
        }
​
        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_mutex_destroy(&nutex);
        return 0;
}
/*
found thread succeed
t1:id=140562014590720
t1:data=1
found thread succeed
main:id=140562023094080
main:1
t2:id=140562006198016
main:1
t1:data=2
t1:data=3
t1 quit =============================
main:2
t2:data=4
main:4
t2:data=5
t2:data=6
main:6
*/

2.3、条件pthread_cond_init,pthread_cond_destroy,pthread_cond_wait,pthread_cond_timewait,pthread_cond_signal,pthread_cond_broadcast

静态态初始化,pthread_cond_t cond = PTHREAD_COND_INITIALIER;
动态初始化,int pthread_cond_init(pthread_cond_t *cond, thread_condattr_t *cond_attr);

功能:创建

参数:全局变量,指针属性NULL

int pthread_cond_destroy(pthread_cond_t *cond);

功能:销毁

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);

功能:等待

参数:cond,nutex

int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);

功能:触发,广播

例子:

  1. 2个线程,锁,条件初始化
  2. 线程1等待条件
  3. 线程2加锁data++,触发条件
  4. 线程1执行
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
​
int data = 0;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t nutex = PTHREAD_MUTEX_INITIALIZER;
​
​
void *fun1(void *arg)
{
        while(1){
                pthread_cond_wait(&cond, &nutex);
                printf("t1:%d\n",data);
                data = 0;
        }
}
​
void *fun2(void *arg)
{
        while(1){
                pthread_mutex_lock(&nutex);
                data++;
                pthread_mutex_unlock(&nutex);
                printf("t2:data=%d\n",data);
                if(data == 3){
                        pthread_cond_signal(&cond);
                }
                sleep(1);
        }
        pthread_exit(NULL);
}
​
int main()
{
        pthread_t t1;
        pthread_t t2;
        pthread_mutex_init(&nutex, NULL);
        pthread_create(&t1,NULL,fun1,NULL);
        pthread_create(&t2,NULL,fun2,NULL);
​
        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_cond_destroy(&cond);
        pthread_mutex_destroy(&nutex);
        return 0;
}
/*
t2:data=1
t2:data=2
t2:data=3
t1:3
t2:data=1
t2:data=2
t2:data=3
t1:3
t2:data=1
t2:data=2
t2:data=3
t1:3
*/