Linux Learning 5-Threading

Source: Internet
Author: User
Tags terminates

Thread 1.1 What is a thread?

Multiple lines of execution in a program are called Threads (thread). A more accurate definition is that a thread is a control sequence within a process.

To figure out the difference between a fork system call and creating a new thread. When a process executes a fork call, a new copy of the process is created. This new process has its own variables and its own PID, and its time schedule is also independent, its execution (usually)

Almost completely independent of the parent process. When a new thread is created in the process, the new execution thread will have its own stack (and hence its own local variable), but share global variables, file descriptors, signal processing functions, and current directory state with its creator. 

1.2 First thread of the threaded

Threads have a complete set of related function library calls, most of them beginning with Pthread_. In order to use these function calls, we must define the macro _reentrant, include the header file Pthread.h in the program, and need to use the option-lpthread to link libraries when compiling the program.

In a multithreaded scenario, by default, there is only one errno variable for all threads to share. When a thread is ready to get the error code, the variable is easily changed by a function call in another thread. Similar problems exist in functions such as fputs, which typically use a separate global region to cache output data.

To solve this problem, you need to use a reentrant routine. Reentrant code can be called multiple times and still works fine. A multithreaded program written to tell the compiler that we need reentrant functionality by defining the macro _reentrant, which must appear before any # include statements in the program.

_reentrant did three things for us and was very elegant:

(1) It will redefine their safe reentrant versions of some functions, the names of which generally do not change, except that the _r string will be added after the function name, such as the name gethostbyname into Gethostbyname_r.

(2) Some functions that were originally implemented as macros in Stdio.h will become safe reentrant functions.

(3) The variable error defined in Error.h will now become a function call that can obtain the true errno value in a secure multithreaded manner.

For example, it is easy to understand the importance of re-entry in a better sense:

int 1; // define a global variable void Add () {    g_val+ +;}

If there are n threads calling this function, G_val is a global variable, and if you add-D _reentrant, you can re-enter, that is, g_val is not affected by other threads, but when you do not add-D _reentrant, the variable n-1 will affect each other when a g_val thread calls the function , and unexpected results occur.

The reason for this is that the function is called after adding-D _reentrant, but the difference is that the mechanism automatically turns the above function into a

void Add_r () {    g_val+ +;}

The function called is different.

To create a new thread function:

#include <pthread.h>

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

The first parameter, thread, points to a pointer to the pthred_t type data. When a thread is created, the pointer to a variable is written to an identifier, which we use to refer to the new thread.

The second parameter is used to set the properties of a thread. Special properties are generally not required, so it can be set to null.

The third parameter is a function address that returns a pointer to void with a pointer to void.

When called with Fork, the parent-child process will continue to execute in the same position, except for the return value of the fork call;

But for the new thread, we have to explicitly give it a function pointer, and the new thread will start executing at this new location.

The fourth parameter is a parameter to pass to the above function (the third argument).

The return value is 0 if the function call succeeds, and an error code is returned if it fails.

function to terminate the thread:

#include <pthread.h>

void Ptherad_exit (void *retval);

The thread terminates execution by calling the Pthread_exit function as if the process had called the Exit function at the end. The function is to terminate the thread that invokes it and return a pointer to an object.

Note that it must never be used to return a pointer to a local variable, because the local variable is no longer present after the thread calls the function, which causes a serious program vulnerability.

Functions waiting for a thread:

#include <pthread.h>

int Pthread_join (pthread_t th, void **thread_return);

The role of the Pthread_join function in a thread is equivalent to the wait function that is used to collect the child process information in the process.

The first parameter specifies the thread to wait for, and the thread is specified by the identifier returned by Pthread_create.

The second argument is a pointer to another pointer, which points to the return value.

This function successfully returns a 0 failure return error code.

Sample code for the first thread:

#include <stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<pthread.h>void*thread_function (void*Arg);Charmessage[]="Hello world!";intMain () {intRes;    pthread_t A_thread; void*Thread_result; Res= Pthread_create (&a_thread,null,thread_function, (void*) &message); if(Res! =0) {perror ("Create thread is failed\n");         Exit (Exit_failure); } printf ("waiting for thread to finish...\n"); Res= Pthread_join (a_thread,&Thread_result); if(res!=0) {perror ("thread Join failed!\n");          Exit (Exit_failure); } printf ("Thread joined,it return%s\n",(Char*) thread_result); printf ("message now is%s\n", message);    Exit (exit_success); }void*thread_function (void*Arg) {printf ("Th_func is Running,aragement was%s\n",(Char*) arg); Sleep (5); strcpy (Message,"Bye"); Pthread_exit ("Thanks for the CPU time\n"); }

Execution Result:

When compiling this program, we need to define the macro _reentrant first. On a few systems, you may also need to define macro _posix_c_source. (However, I do not have the ability to implement the function, pending resolution)

Next you must link the correct line libraries.

My system default line libraries is NPTL (view header file/usr/include/pthread.h If display copyright date in 2003 or later, that basic your Linux distribution uses NPTL implementation)

Compile and link using the following command:

Cc-d_reentrant Thread1.c-o Thread1-lpthread

PS: I changed cc to GCC for compilation.

Analysis: The main function continues execution after a successful creation of a new thread. It then executes the Pthread_join function until the thread it specifies terminates before returning. The main thread then prints the new threaded return value and the global variable ends.

The newly created thread will execute the thread_function. First print your own parameters, and after sleep 5S, change the global variable to return a string to the main thread when you finally exit.

Linux Learning 5-Threading

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.