Linux programming-the first Thread program (chapter 12th)

Source: Internet
Author: User
Tags terminates

12th. POSIX threads in chapter 11th, describes how to process processes in Linux. But sometimes it's considered too expensive to use fork to create a new process. In this case, it would be useful to have a process do two things at the same time or at least look like this, and People's pages want two or more things to happen in a very tight way at the same time, which requires threading to work.
12.1 What is a thread in multiple lines of execution in a program are called Threads (thread).A more accurate definition is: A thread is a control sequence inside a process.While Linux, like many other operating systems, is good at running multiple processes at the same time, all the programs that have been seen so far have been executed as a separate process. In fact, all processes have at least one thread of execution. So far, all the processes seen have only one thread of execution.
figuring out the difference between fork system calls and creating new threads is important. When a program executes a fork call, a new copy of the process is created. This process has its own variables and its own PID, and its time schedule is also independent, Its execution is almost entirely 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 status with its creator.
Linux system for the first time in 1996 to obtain the support of the thread, often the library used at that time to become linuxthread. It is an important step in Linux programming, which allows Linux programmers to use threads for the first time in a Linux system. But, There is still a slight difference between the Linux thread implementation version and the POSIX standard, most notably with regard to the Signal Processing section. Most of these differences are constrained by the underlying Linux kernel, not by the library implementation.
Many projects are investigating how to improve Linux for threading support, and this improvement is not just about removing the subtle differences between the POSIX standard and Linux implementations, but also to enhance the performance of Linux threads and remove some unwanted restrictions, Much of this work is focused on how to map user-level threads to kernel-level threads. The two main projects in these projects are the next generation of POSIX threads (NGPT) and local POSIX threads (NPTL). All two of these projects have to modify the Linux kernel to support the new function library.
12.2 Thread advantages and disadvantages in some environments, creating new threads has a more obvious advantage than creating new processes new threads are created at a much smaller cost than the process.
threads have some of the following advantages:1. Sometimes it is useful to make the program appear to be doing two things at the same time. A classic example is the real-time statistics of the number of words in a document while the document is being edited. One thread is responsible for processing the user's input and performing the text editing work, and the other (it can also see the same document content) The word count variable is constantly refreshed. The first process uses this shared count variable to keep the user informed of the progress of their work. Another example is a multi-threaded database server, an obvious single-process service for multi-user scenarios. It blocks other requests while responding to some requests, Make it wait for disk operations to improve overall data throughput. For database servers, this obvious multi-tasking task can be difficult to achieve efficiently if it is done in a multi-process manner, because the different processes must work closely together to meet the requirements of lock and data consistency. It is much easier to use multithreading to accomplish than to use multiple processes.
2. A reference program mixed with input, calculation, and output can be executed by separating the parts into 3 threads, improving the performance of the program execution. When the input or output thread waits for a connection, another thread can continue to execute. So if a process can do at most one thing at any one time, Threads can allow it to do other useful things while waiting for things like connections. A server application that needs to handle multiple network connections at the same time is an example of a natural fit for multithreaded applications.
3. In general, switching between threads requires that the operating system does more work than switching between processes, so multiple threads need more resources than many processes. If a program logically requires multiple threads of execution, It is more realistic to run it as a multithreaded program on a single-processor system. However, writing a multithreaded design is difficult and should not be taken lightly.
threads also have some of the following drawbacks: 1. Writing multithreaded programs requires very careful design, and in multithreaded programs, the likelihood of errors caused by subtle deviations in timing or accidental sharing of variables is significant.
2. Debugging multithreaded threads is much more difficult than debugging a single-threaded thread, because the interaction between them is very difficult to control
3. A program that divides a large number of calculations into two parts and runs the two parts as two different threads does not necessarily run faster on a single-processor machine, unless the calculation does allow its different parts to be computed simultaneously, and the machine that runs it has multiple processor cores to support true multi-processing.
12.3 First thread of the threaded threads have a complete set of function library calls associated with them, with the vast majority of function names beginning with Pthread_. In order to use these library calls, you must define a macro _reentrant that contains the header file Pthread.h in your program. And you need to use the option-lpthread to link the wiring when compiling the program libraries.
When designing the initial UNIX and POSIX library routines, it was assumed that there was only one thread of execution per process, and an obvious example was errno, which was used to get the error message after a function call failed. In a multithreaded application, 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 in another thread. Similar problems exist with functions such as fputs, which typically use a global region to cache output data.
To solve this problem, you need to use a routine called reentrant. Reentrant code can be called multiple times and still work, and these calls can come from different threads or some form of nested invocation. Therefore, the reentrant part of the code usually uses only local variables. This makes each call to the code get its own unique copy of the data.
When you write a multithreaded program, by defining a macro _reentrant to tell the compiler that a reentrant function is required, the definition of the macro is in front of any # include statements in the application, it does 3 things, and it does so gracefully that it generally does not need to know exactly what it is doing.
1. It will redefine their safe re-entry versions of some functions whose names generally do not change, except that the _r string is added after the function name. For example, the functions name gethostbyname will become Gethostbyname_r.
Some functions that were originally implemented as macros in 2.stdio.h will become safe reentrant functions
3. The variable errno defined in Errno.h will now be a function call that can obtain a true errno value in a multithreaded and secure manner
Include header files in your program pthread.h will also provide some other definitions and function prototypes that will be used in your code, just as the header file stdio.h for standard input and standard input routines. Finally, you need to make sure that the correct header file is included in the program. It also links the correct line libraries to implement the Pthread function when compiling the program. First look at a new function for managing threads Pthread_create, its role is to create a new thread, similar to the fork function that creates a new process, which is defined as follows:
#include <pthread.h>int pthread_create (pthread_t *thread, pthread_attr_t *attr, void * (*start_routine) (void*), void *arg);
The first parameter is a pointer to the data of type pthread_t. When a thread is created, the variable that the pointer points to is written to an identifier, which is used to introduce a new thread.
The second parameter is used to set the properties of the thread. Typically, you do not need special attributes, just set to null.
The third argument tells the thread to start executing the function
The fourth parameter is the argument passed to the function that initiates the execution
void * (Start_routine) (void *)
The above line indicates that a function address must be passed with a pointer to void, which returns a pointer to void.
Therefore, you can pass a parameter of any type and return a pointer of any type. When called with Fork, the parent-child process will continue to execute in the same location, but the return value of the fork call is different, but for the new thread it must be explicitly provided with a function pointer, and the new thread will start executing at this position. .
The successful return value of the function call is 0, and the error code is returned if it fails.
The thread terminates execution by calling the Pthread_exit function, just as the process calls the Exit function at the end. This function terminates the thread that invokes it and returns a pointer to an object. It must never be used to return a pointer to a local variable, because after the thread calls the function, This local variable does not exist. The definition of the Pthread_exit function is as follows:
#include <pthread.h>void pthread_exit (void *retval);
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 definition of this function is as follows:
#include <pthread.h>int pthread_joint (pthread_t th, void **thread_return);
The first parameter specifies the thread to wait for the thread to specify by pthread_create the identifier returned by the
The second argument is a pointer to another pointer, which points to the return value of the thread. Similar to Pthread_create, this function returns 0 on success and returns an error code if it fails.
Writing thread1.c, this program creates a new thread, the new thread shares the variable with the original thread, and returns a result to the original thread at the end.
/************************************************************************* > File name:thread1.c > DESCRIPTION:THREAD1.C creates a new thread, the new thread shares the variable with the original thread, and returns a result to the original thread at the end > Author:liubingbing > Created time:2015 Year 07 04th Saturday 20:50 31 sec > Other: When compiling the THREAD1.C program, you need to define the macro _reentrant, and use the option-lpthread to link the libraries. Use the command gcc-d_reentrant thread1.c-o thread1-lpthread **************************************************************** /#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h># Include <pthread.h>void *thread_function (void *arg), char message[] = "Hello world"; int main () {int res;pthread_t A_ Thread;void *thread_result;/* Pthread_create is similar to the fork function, which creates a new thread that returns 0 * when created successfully * The first parameter is a pointer to the pthread_t type data. The pointer to the variable to write an identifier to introduce a reference to the new thread * The second parameter is used to set the thread property, which is generally null * The third parameter is the function to which the thread will start executing * The fourth parameter is the argument passed to the function */res = Pthread_create ( &a_thread, NULL, thread_function, (void *) message), if (res! = 0) {perror ("Thread creation failed"); Exit (exit_failure );} PrinTF ("Waiting for Thread to finish...\n");/* Pthread_join similar to the wait function used to collect information about a child process, returns 0 * On success The first parameter specifies the thread that will be waiting, and the thread passes Pthread_ The identifier returned by create specifies that the second argument is a pointer to another pointer, which returns the return value of the waiting thread */res = Pthread_join (A_thread, &thread_result); if (res! = 0) { Perror ("Thread join Failed"); exit (exit_failure);} printf ("Thread joined, it returned%s\n", (char *) thread_result);p rintf ("message is now%s\n", message); Exit (Exit_ SUCCESS);} void *thread_function (void *arg) {printf ("Thread_function is running. Argument was%s\n ", (char *) arg); sleep (3); strcpy (Message," bye! "); * Pthread_exit terminates calling its thread and returns a pointer to an object */pthread_exit ("Thank for the CPU Time");}
You first define the prototype of a function that needs to be called by the thread when it is created, as follows:
void *thread_function (void *arg);
According to Pthread_create, it only has a pointer to void as a parameter and returns a pointer to void.
In the main function, you define several variables, and then call Pthread_create to start running the new thread as follows:
pthread_t a_thread;void *thread_result;res = pthread_create (&a_thread, NULL, thread_function, (void *) message);
The address of an pthread_t type object is passed to the Pthread_create function, which can be used to refer to the new thread. The second parameter is set to NULL. The last two parameters are the function to be called and a parameter passed to the function.
If the call succeeds, there are two threads running, the original thread (main) continues executing the code behind Pthread_create, and the new thread starts executing the thread_function function.
The original thread will call the Pthread_join function after it finds out that a new thread has started to start, as follows:
res = Pthread_join (A_thread, &thread_result);
Pass two parameters to the function, one is the identifier of the thread that is waiting for it to end, and the other is a pointer to the thread's return value. This function will wait until the thread it specifies terminates before returning. The main thread then quotes the value of the return value and global variable message for the new threads and finally exits.
The new thread begins execution in the Thread_function function, which prints its own parameters, sleeps for a while, then updates the global variables, exits and returns a string to the main thread. The new thread modifies the array message, The original thread can also access the array. If you call fork instead of pthread_create, there is no such effect.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Linux programming-the first Thread program (chapter 12th)

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.