10. Operating system - related attributes of threads (2)

Table of contents

1. Thread scheduling

1. Three scheduling algorithms

(1) SCHED_FIFO (first in first out queuing scheduling)

(2) SCHED_RR real-time scheduling strategy, time slice rotation

(3) SCHED_OTHER time-sharing scheduling strategy (linux default)

 2. pthread_attr_setschedpolicy/pthread_attr_getschedpolicy (get and set thread scheduling policy)

 2. Thread stack closes warning area

1. pthread_attr_setstacksize/pthread_attr_getstacksize (get, set thread stack size, warning area size)

 2. Each thread has a relatively independent stack

3. Thread exit

1. pthread_exit (thread exits by itself)Edit

         2. pthread_cancel (thread cancellation) (please thread exit)

3. Create a thread, send a request to cancel the thread after 1s, and the thread terminates

1. Thread scheduling

1. Three scheduling algorithms

(1) SCHED_FIFO (first in first out queuing scheduling)

If the static priority is set to 1-99, if the thread is in the ready state, it can immediately preempt the ordinary thread with a static priority of 0.

a. When ready, put it at the end of the priority queue

b. After being preempted by a thread with a higher priority, it will be placed at the head of the priority queue . When all threads with a higher priority than him are no longer running, they will resume running

c. After calling sched_yield(), it will be placed at the end of the priority queue

Summary: The thread will run until it sends an I/O request, or is preempted by a higher priority thread, or calls sched_yield() to actively give up the CPU

(2) SCHED_RR real-time scheduling strategy, time slice rotation

Similar to SCHED_FIFO, the difference is that the time slice is set. When the time slice is exhausted, it will be placed at the end of the priority queue . You can use sched_rr_get_interval( ) to get the specific value of the time slice.

(3) SCHED_OTHER time-sharing scheduling strategy (linux default)

Static priority must be set to 0

These threads at priority level 0 are scheduled according to the so-called dynamic priority, and the dynamic priority starts from the nice value of the thread, and whenever a thread is already in the ready state but ignored by the scheduler, its dynamic priority will be Automatically increase by one unit, so as to ensure the fairness of these threads competing for the CPU.

 2. pthread_attr_setschedpolicy/pthread_attr_getschedpolicy (get and set thread scheduling policy)

 2. Thread stack closes warning area

1. pthread_attr_setstacksize/pthread_attr_getstacksize (get, set thread stack size, warning area size)

 2. Each thread has a relatively independent stack

The stack of the thread may overflow, and the stack space needs to be increased. Because there is a warning area, there is no need to do this. The warning area is memory without any access rights, and is used to protect the stack space of two adjacent threads from being trampled on each other.

3. Thread exit

1. pthread_exit (the thread exits by itself)

 2. pthread_cancel (thread cancellation) (please thread exit)

 At a certain moment, you can't wait for a thread to "naturally die" (for example, in while(1)), you need to make it end immediately, you can send a cancel request to the thread, let it interrupt the execution and exit.

And when a thread receives a cancel request, how it behaves depends on two things:

One is the current cancellation status:

         PTHREAD_CANCEL_ENABLE enable (cancel is allowed. default) PTHREAD_CANCEL_DISABLE disable (cancel not allowed)

The second is the current cancellation type:

        Delayed response waits for a thread to respond to a canceled request when it encounters a cancellation point

        Respond immediately

3. Create a thread, send a request to cancel the thread after 1s, and the thread terminates

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

void * func (void * arg)
{
    int * p = calloc(1,4);
    while(1)
    {
        printf("这里是func线程,线程ID :%ld \n" , pthread_self() );
        sleep(1);
    }

    *p = 1024 ;
    // 退出本线程并设置返回值的地址(返回了num 的地址)
    pthread_exit((void *)p); //返回的内存地址应该时一个堆空间
}

int main(int argc, char const *argv[])
{
    
    // 创建线程
    pthread_t t_id  = -1 ;
        
    pthread_create( &t_id , //新线程ID号
                    NULL , // 线程属性, NULL 默认属性
                    func,  // 线程需要执行的例程(新线程需要执行的任务《函数》) 
                    NULL ); // 线程的参数

    printf("t_id : %ld\n" , t_id) ;

    printf("这里是主函数,线程ID :%ld \n" , pthread_self() );

    int * retval ;
    int ret_val = 0 ;

    sleep(1);
    pthread_cancel( t_id );

    // 阻塞等待接合线程
    printf("等待 function 线程退出:\n");
    if( ret_val = pthread_join( t_id , (void*)&retval))
    {
        fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
    }
    printf("结合线程成功, 退出值为:%d\n" , *retval);

    // 尝试接合线程  (非阻塞)
    // int ret_val = 0 ;
    // if( ret_val = pthread_tryjoin_np( t_id , (void*)&retval))
    // {
    //     fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
    // }

    return 0;
}

The above example can cancel the thread, but there is no way to combine the exit value of the thread

Guess you like

Origin blog.csdn.net/weixin_45981798/article/details/129813932