Thread Control for Poosix of LInux

Keywords: Linux

1. Thread Control Chart

Main Thread<->|Work Queue|<->Work 1<->Work 2<->Work 3
Thread 1<-> | Work Queue |<->Work 1<->Work 2<->Work 3
Thread 2<->|Work Queue|<->Work 1<->Work 2<->Work 3
Thread 3<->|Work Queue|<->Work 1<->Work 2<->Work 3

Second, the thread's identifier

  Similar to process identifiers, each thread has a unique thread identifier (thread ID) in the process, which is represented by the data type pthread_t, which is essentially an unsigned long integer in Linux.

LInux provides two functions for identifying threads with the following standard call format:
#include <pthread.h>
pthread_t pthread_self(void);
The pthread_self function is used to get the thread identifier of the thread itself, and its return value is the thread identifier of the thread itself.
The pthread_equal function is used to compare two thread identifiers, and its standard call format is described below:
#include <pthread.h>
int pthread_equal(pthread_tid, pthread_t tid2);

3. Thread Control Related Functions

To compile a multithreaded program using gcc, you must link to the pthread library and compile it under the terminal using the following gcc-lpthread

1,pthread_create function

Document description

NAME
       pthread_create - create a new thread

SYNOPSIS
       #include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

       Compile and link with -pthread.

DESCRIPTION
       The  pthread_create()  function  starts  a  new  thread  in the calling
       process.  The new thread starts execution by invoking  start_routine();
       arg is passed as the sole argument of start_routine().

       The new thread terminates in one of the following ways:

       * It  calls  pthread_exit(3),  specifying  an exit status value that is
         available  to  another  thread  in  the  same  process   that   calls
         pthread_join(3).

An example

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

pthread_t ntid; //Thread id

//Functions to print identifiers
void printds(const char *s)
{
    pid_t pid; //Process Identifier
    pthread_t tid;  //Thread Identifier

    pid = getpid(); // Get process identifier id
    //Gets the id of the thread identifier
    tid = pthread_self();  


    printf("%s pid, %u tid %u (0x%x)\n", s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);  //Print process and thread id
}

//Functions that start running in a thread
void *thr_fn(void *arg)
{
    printds("new thread:");
    return ((void*)0);
}

int main(void)
{
    int err;
    err = pthread_create(&ntid, NULL, thr_fn, NULL);  //Create a thread

    // Print financial label if error occurs
    if (err != 0)
    {
        printf("can't create thread %s\n", strerror(err));
    }

    //Print main thread number
    printds("main thread:");

    sleep(1);
    exit(0);
    return 0;
}

You can see that the process with the identifier 7738 created two threads with the identifiers 2274588416 and 22266298112, respectively.

2,pthread_exit function
A process can call the exit series function to exit the current process, or a thread can exit in three ways, and stop the thread's control flow without terminating the entire process.
1, the thread is only returned from the startup column type, the return value is the thread's exit code.
2. Threads can be terminated by other processes in the same process.
3, the thread calls the pthread_exit function to exit
The Linux kernel provides pthread_exit functions to actively exit threads, which are prototyped in the LInux library:

NAME
       pthread_exit - terminate calling thread

SYNOPSIS
       #include <pthread.h>

       void pthread_exit(void *retval);

       Compile and link with -pthread.

DESCRIPTION
       The pthread_exit() function terminates the calling thread and returns a
       value via retval that (if the  thread  is  joinable)  is  available  to
       another thread in the same process that calls pthread_join(3).

       Any  clean-up handlers established by pthread_cleanup_push(3) that have
       not yet been popped, are popped (in the reverse of the order  in  which
       they  were pushed) and executed.  If the thread has any thread-specific
       data, then, after the clean-up handlers have been executed, the  corre‐
       sponding destructor functions are called, in an unspecified order.

3. The pthread_join function My understanding is to execute the pthread_create function without the pthread_join function
If a thread can be blocked by other threads after it has finished executing, and then wait for the specified thread to call pthread_exit to return from the boot or cancel, the LInux kernel can call the pthread_join function to complete the blocking of the thread. Its prototype in the LInux function library is:

NAME
       pthread_join - join with a terminated thread

SYNOPSIS
       #include <pthread.h>

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

       Compile and link with -pthread.

DESCRIPTION
       The pthread_join() function waits for the thread specified by thread to
       terminate.  If that thread has already terminated, then  pthread_join()
       returns immediately.  The thread specified by thread must be joinable.

       If  retval  is  not NULL, then pthread_join() copies the exit status of
       the target thread (i.e., the value that the target thread  supplied  to
       pthread_exit(3))  into the location pointed to by *retval.  If the tar‐
       get thread was canceled, then PTHREAD_CANCELED is placed in *retval.

       If multiple threads simultaneously try to join with  the  same  thread,

Return: If the call is successful, the function returns 0 and vice versa, a non-zero value

Example:

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

void print_msg(char *ptr);


int main(void)
{
    pthread_t thread1, thread2;
    int i, j;
    void *retval;

    char *msg1 = "This is the frist thread\n";
    char *msg2 = "This is the second thread\n";


    pthread_create(&thread1, NULL, (void *)(&print_msg),(void *)msg1);

    pthread_create(&thread2, NULL, (void *)(&print_msg), (void *)msg2);  //Create two threads

    pthread_join(thread1, &retval);
    pthread_join(thread2, &retval);
    return 0;
}

//Print Information Function, from which the thread executes
void print_msg(char *ptr)
{
    int i;
    for( i = 0; i < 10; i++)
    {
        //Continuous output of 10 strings
        printf("%s\n", ptr); 
    }
}

Running Effect Diagram

4,pthread_cancel function

Return: If the operation returns 0 successfully, the failure returns the corresponding error code

5,pthread_cleanup_push and pthread_cleanup_pop functions
When the pthread_cancel function is called to cancel a thread, the corresponding function needs to be called to clean up the environment after the process exits.

1, when calling the pthread_exit function
2, in response to a cancellation request
3, when pthread_cleanup_pop is called with a non-execute parameter

6,pthread_detach function

Posted by Ludo Lambrechts on Sun, 16 Jun 2019 10:04:56 -0700