线程详解(下)

吃可爱长大的小学妹 提交于 2019-11-26 04:57:55

四·线程函数

1. 创建线程

#include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
  • 功能:创建线程
  • thread:获取线程ID
  • attr:创建线程时所需要的属性设置,如果为NULL按照默认方式创建线程。
  • start_routine:线程的入口函数
  • arg:给线程入口函数传递的参数
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
void* start_run(void* arg)
{
    printf("--%s--\n",(char*)arg);
    while(1)
    {
        printf("*");
        fflush(stdout);
        sleep(1);
    }int main()
{
    char* str = "aaaa";
    pthread_t pid;
    pthread_create(&pid,NULL,start_run,str);
    while(1)
    {
        printf("#");
        sleep(1);
    }
}
//gcc -lpthread
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
void* start_run(void* arg)
{
    int clifd = *(int*)arg;
    printf("%d ",clifd);
}
int main()
{
    for(int i=0;i<10000;i++)
    {
        int clifd =i ;
        pthread_t pid;
        pthread_create(&pid,NULL,start_run,&clifd);
    }
}

2. 等待线程结束

int pthread_join(pthread_t thread, void **retval);
  • 功能:等待线程结束获取线程入口函数的返回值,线程结束时该函数才返回。
  • thread:线程ID
  • retval:指针变量的地址,用于获取线程入口函数的返回值。

注意:线程入口函数在返回数据时,不能返回指向私有栈空间的指针。如果获取到的是指向堆的指针,等待者要负责把该空间释放。

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

void* start_run(void* arg)
{
    char* str = "--------";
    return str;
}

int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,start_run,NULL);
    void* ptr = NULL;
    pthread_join(pid,&ptr);
    printf("%p\n",ptr);
}

3. 获取线程ID

 pthread_t pthread_self(void);
  • 功能:返回当前线程的ID。

4. 比较两个线程ID

int pthread_equal(pthread_t t1, pthread_t t2);
  • 功能:如果两个线程ID是同一个线程,则返回0,否则返回-1.

注意:pthread_t不一定是 unsigned long 类型,有些系统中它是结构体类型,所以无法使用==比较。

5. 线程终止

void pthread_exit(void *retval);
  • 功能:调用者线程结束(从入口函数return)
  • retval:这个参数会返回给pthread_join函数的第二个参数。

注意:如果是进程的最后一个线程,当调用pthread_exit时进程也就结束了。

6. 线程分离

  • 非分离:线程可以被创建者调用pthread_join等待(回收资源)。
  • 分离状态:线程不需要创建者等待,结束后自动释放资源。
int pthread_detach(pthread_t thread);
  • 功能:使用调用线程与线程ID为thread线程成为分离状态。
  • 例子
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

void* start_run(void* arg)
{
    char* str = "--------";
    sleep(3);
    return str;
}

int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,start_run,NULL);
    pthread_detach(pid);

    void* ptr = NULL;
    pthread_join(pid,&ptr);
    printf("%p******\n",(char*)ptr);
}

7. 线程取消

 int pthread_cancel(pthread_t thread);
  • 功能:向指定的线程发送取消操作

注意:对方不一定响应。

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

void* start_run(void* arg)
{
    while(1)
    {
        printf("-----------");
        sleeo(1);
    }
}

int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,start_run,NULL);

    pthread_cancel(pid);
    pthread_join(pid,&ptr);
}
int pthread_setcancelstate(int state, int *oldstate);
  • 功能:设置当前调用者线程是否响应取消操作。
  • state:
    • PTHREAD_CANCEL_ENABLE允许响应
    • PTHREAD_CANCEL_DISABLE禁止响应
  • oldstate:获取旧的状态

8. 设置线程属性

typedef union
{
char _size[_SIZEOF_PTHREAD_ATTR_T];
long int _align;
}prhread_attr_t;

  • 猜测:不让手动修改线程
int pthread_attr_init(pthread_attr_t *attr);
  • 功能:初始化线程属性
int pthread_attr_destroy(pthread_attr_t *attr);
  • 功能:销毁线程属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
  • 1功能:设置线程属性中分离标志
  • 2功能:获取线程属性中分离标志。
  • PTHREAD_CREATE_DETACHED 分离
  • PTHREAD_CREATE_JOINABLE 不分离
int pthread_attr_setscope(pthread_attr_t *attr, int scope);
int pthread_attr_getscope(pthread_attr_t *attr, int *scope);
  • 1功能:设置线程属性中线程的竞争范围
  • 2功能:获取线程属性中线程的竞争范围
  • PTHREAD_SCOPE_SYSTEM
  • PTHREAD_SCOPE_PROCESS
int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);
int pthread_attr_getinheritsched(pthread_attr_t *attr,int *inheritsched);
  • 1功能:设置线程属性中线程的调度策略的来源
  • 2功能:获取线程属性中线程的调度策略的来源
  • inheritsched
    • PTHREAD_INHERIT_SCHED 继承创建者
    • PTHREAD_EXPLICIT_SCHED 单独设置
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);
  • 1功能:设置线程属性中线程的调度策略

  • 2功能:获取线程属性中线程的调度策略

  • SCHED_FIFO 先进先出策略

  • SCHED_RR 轮转策略

  • SCHED_OTHER 缺省

int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);
int pthread_attr_getschedparam(pthread_attr_t *attr,struct sched_param *param);
  • 1功能:设置线程属性中线程的调度参数(优先级别)。
    • 最高级别0
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
  • 1功能:设置线程属性中栈尾的警戒区大型,默认一页
  • 2功能:获取线程属性中栈尾的警戒区大型
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);
int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);
  • 1功能:设置线程属性中线程的栈底地址
  • 2功能:获取线程属性中线程的栈底地址
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
  • 1功能:设置线程属性中线程的栈空间字节数

  • 2功能:获取线程属性中线程的栈空间字节数

  • 使用方法:

    1. 定义线程属性结构体
    • pthread_attr_t attr;
    1. 初始化线程属性结构体
    • pthread_attr_init(&attr);
    1. 使用pthread_attr_set系列函数对结构变量进行设置
    2. 在创建函数时(pthread_create函数的第二个参数中使用线程属性结构变量创建线程)。
int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
  • 功能:获取指定线程的属性。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!