创建线程:pthread_create

2022-07-20 10:18:15 浏览数 (1)

大家好,又见面了,我是全栈君。

int pthread_create((pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) 若线程创建成功,则返回0。若线程创建失败,则返回出错编号,并且*thread中的内容是未定义的

int pthread_join(pthread_t thread, void **retval); 以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的

int pthread_detach(pthread_t tid); 调用pthread_join(pthread_id)后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此,比如在Web服务器中当主线程为每个新来的链接创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的链接),这时可以在子线程中加入代码pthread_detach(pthread_self())或者父线程调用pthread_detach(thread_id)(非阻塞,可立即返回)

pthread_t pthread_self(void); 获得线程自身的ID。pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则显示结果出问题。

void pthread_exit(void* retval); 线程通过调用pthread_exit函数终止执行,就如同进程在结束时调用exit函数一样。这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。

int pthread_cancel(pthread_t thread) 发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。 http://www.cnblogs.com/lijunamneg/archive/2013/01/25/2877211.html

int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr); 作用是初始化一个线程对象的属性,需要用pthread_attr_destroy函数对其去除初始化。 Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); attr 是线程属性变量;stacksize 则是设置的堆栈大小。 返回值0,-1分别表示成功与失败。 堆栈最小值定义为 PTHREAD_STACK_MIN ,包含#include <limits.h>后可以通过打印其值查看。对于默认值可以通过pthread_attr_getstacksize (&attr, &stack_size); 打印stack_size来查看。

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); 设置线程调度策略;POSIX 标准指定了三种调度策略:先入先出策略 (SCHED_FIFO)、循环策略 (SCHED_RR) 和自定义策略 (SCHED_OTHER)。SCHED_FIFO 是基于队列的调度程序,对于每个优先级都会使用不同的队列。SCHED_RR 与 FIFO 相似,不同的是前者的每个线程都有一个执行时间配额。SCHED_FIFO 和 SCHED_RR 是对 POSIX Realtime 的扩展。SCHED_OTHER 是缺省的调度策略。

int pthread_attr_setscope (pthread_attr_t* attr, int scope); POSIX的标准中定义了两个值:PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU。默认为PTHREAD_SCOPE_PROCESS。

int pthread_attr_setdetachstate (pthread_attr_t* attr, int detachstate); 该表示新线程是否与进程中其他线程脱离同步,如果设置为PTHREAD_CREATE_DETACHED则新线程不能用pthread_join()来同步,且在退出时自行释放所占用的资源。缺省为PTHREAD_CREATE_JOINABLE状态。这个属性也可以在线程创建并运行以后用pthread_detach()来设置,而一旦设置为PTHREAD_CREATE_DETACH状态(不论是创建时设置还是运行时设置)则不能再恢复到PTHREAD_CREATE_JOINABLE状态。

int pthread_attr_setschedparam (pthread_attr_t* attr, struct sched_param* param); int pthread_attr_getschedparam (pthread_attr_t* attr, struct sched_param* param); 一个struct sched_param结构,目前仅有一个sched_priority整型变量表示线程的运行优先级。这个参数仅当调度策略为实时(即SCHED_RR或SCHED_FIFO)时才有效,并可以在运行时通过pthread_setschedparam()函数来改变,缺省为0

int pthread_setschedparam(pthread_t target_thread, int policy, const struct sched_param *param) 用于设置线程的调用策略和优先级。

int pthread_attr_getinheritsched(const pthread_attr_t *attr,int *inheritsched); int pthread_attr_setinheritsched(pthread_attr_t *attr,int inheritsched);

设置线程的继承属性,PTHREAD_INHERIT_SCHED: 新的线程继承创建线程的策略和参数;PTHREAD_EXPLICIT_SCHED:新的线程继承策略和参数显示指定。

代码语言:javascript复制
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#ifndef T_DESC
#define T_DESC(x, y)   (y)
#endif

#if T_DESC("global", 1)
pid_t gettid(void)
{  
    return syscall(SYS_gettid);  
} 
#endif

#if T_DESC("TU1", 1)
void thread_1(void)  
{  
    int i;  

    for(i=0; i<10; i  )  {
        printf("thread_1: pid=0x%x tid=0x%x self=0x%xn", getpid(), gettid(), (int)pthread_self());
        sleep(1);  
    }  
    pthread_exit(0);  
}  
  
void thread_2(void)  
{  
    int i;  
    
    for(i=0; i<5; i  ) {
        printf("thread_2: pid=0x%x tid=0x%x self=0x%xn", getpid(), gettid(), (int)pthread_self());
        sleep(1);  
    }  
    pthread_exit(0);  
}  
  
int tu1_proc(void)  
{  
    pthread_t id_1,id_2;  
    int ret;  
    unsigned long stack_size;
    pthread_attr_t attr;
    struct sched_param sched;

    pthread_attr_init(&attr);
    sched.sched_priority = 80;
    //pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
    //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); //会导致线程创建失败
    
    pthread_attr_getstacksize(&attr, &stack_size);
    printf("default stack size is %ld(k)n", stack_size/1024);

    printf("SCHED_FIFO: Max %u, Min %un", sched_get_priority_max(SCHED_FIFO), sched_get_priority_min(SCHED_FIFO));
    printf("SCHED_RR: Max %u, Min %un", sched_get_priority_max(SCHED_RR), sched_get_priority_min(SCHED_RR));
    printf("SCHED_OTHER: Max %u, Min %un", sched_get_priority_max(SCHED_OTHER), sched_get_priority_min(SCHED_OTHER));

    ret = pthread_create(&id_1, &attr, (void *)thread_1, NULL);  
    if(ret != 0)  
    {  
        printf("Create pthread error!n");  
        return -1;  
    }  
    
    ret = pthread_create(&id_2, &attr, (void *)thread_2, NULL);  
    if(ret != 0)  
    {  
        printf("Create pthread error!n");  
        return -1;  
    }  

    printf("main: pid=0x%x tid=0x%x self=0x%xn", getpid(), gettid(), (int)pthread_self());
    
    /*等待线程结束*/  
    pthread_join(id_1, NULL);  
    pthread_join(id_2, NULL);  
    return 0;  
}  
#endif

#if T_DESC("TU2", 1)

#endif

#if T_DESC("global", 1)
void usage()
{
    printf("n Usage: <cmd> <tu>");
    printf("n    1 -- base case");
    printf("n    2 -- todo ");
    printf("n");
}

int main(int argc, char **argv)
{
    int ret;
    
    if(argc < 2) {
        usage();
        return 0;
    }

    int tu = atoi(argv[1]);
    if (tu == 1) ret = tu1_proc();
    
    return ret;
}
#endif

#if T_DESC("readme", 1)
/*
1, compile command
gcc -o thread.out pthread.c -lpthread

*/
#endif

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/108577.html原文链接:https://javaforall.cn

0 人点赞