linux--Threads

Source: Internet
Author: User
Tags posix

Threads

We all know that the execution of a program is done by the process, while the actual execution of the code in the process is a thread to complete, it is the real execution flow. Usually a program is called a thread (threads) in a line of practice. A more accurate definition of this is that the thread is "a control sequence within a process." And all processes have at least one thread of execution.

In general, process and thread relationships are

① process is the basic unit of resource competition
② threads are the most small units of a program's line of practice.

Threading Benefits:

· threads consume much less resources than processes, and creating a new thread is much smaller than creating a new process (threads do not have to open virtual address space)
• Switching between threads requires much less work for the operating system than switching between processes
• The ability to take advantage of the number of concurrent processors
• While waiting for slow I/O operations to end, the program can perform other computational tasks
• Compute-intensive applications that can be run on multiprocessor systems to decompose computations into multiple threads
· I/O intensive applications overlap I/O operations for high performance. Threads can wait for different I/O operations at the same time.

Thread disadvantage

1. Performance loss
A computationally-intensive thread that is rarely blocked by external events often cannot share the same processor with its threads. If the number of compute-intensive threads is more than the available processors, then there may be a significant performance penalty, and the performance penalty in this case is to increase the additional synchronization and scheduling overhead, while the available resources are the same.
2. Reduced robustness
Multi-Threading requires more in-depth consideration, in a multithreaded program, because of the small deviations in time allocation or the possibility of sharing the variables that should not be shared, the likelihood is very large, in other words, there is a lack of protection between the threads.
3. Lack of access control
A process is the basic granularity of access control, and invoking some system functions in one thread affects the entire process.
4. High level of programming difficulty
Writing and debugging a multithreaded program is much more difficult than a single thread

return value
The global variable errno is not set when all pthreads processing functions are faulted (and most other POSIX functions do). Instead, the error code is returned by the return value. Pthreads also provides errno variables within the thread to support other code that uses errno. However, for errors in the Pthreads function, it is recommended that the return value industry be judged, because reading the return value is less expensive than reading the errno variable within the thread

Related functions

(1) thread identification

The thread ID is the same as the process ID, but the process ID is unique across the system, but the thread ID is different, and it only makes sense in the context of the process to which it belongs. The thread ID is represented by the pthread_t data type, which is represented by a struct, and the portable system cannot treat it like a pid_t type as an integer. so a function is usually used to compare two thread IDs

int pthread_equal (pthread_t tid1, pthread_t Tid2)

At the same time, the thread can get its own thread ID through pthread_self

pthread_t pthread_self (void);

However, it is worth noting that before a thread does not have a process, it corresponds to a process descriptor in the kernel, corresponding to a process ID. But after introducing the threading concept, the situation has changed, a user process under the jurisdiction of N user-state threads, each thread as a separate scheduling entity in the kernel state has its own process descriptor, the process and the kernel of the descriptor has suddenly become a 1:n relationship, The POSIX standard also requires that all threads in the process return the same process ID when they call the Getpid function

Multithreaded processes, also known as thread groups, each thread within a thread group has a process descriptor structure (TASK_STRUCT) corresponding to it in the kernel. The process descriptor structure of the PID, the surface of the corresponding is the process ID, in fact, it corresponds to the thread ID, the Tgid in the process descriptor, meaning the thread Group ID, it corresponds to the user level of the process ID

Linux provides Gettid system tuning to return its thread ID, but GLIBC does not have the system tuned for use by a programmer in an open connect port. If you do need to get the thread ID, you can use the following method:

#include <sys/syscall.h>= Syscall (Sys_gettid);

Example

#include <stdio.h>                                                          #include <sys/syscall.h> #include <pthread.h> #include <unistd.h>  void *route (void *arg) {     pid_t tid = syscall (Sys_gettid);     while (1) {         printf ("Tid =%d, pid=%d\n", Tid, Syscall (sys_getpid));         Sleep (1);     } }  int main (void) {     pthread_t myID;     Pthread_create (&myid, NULL, route, NULL);     pid_t tid = syscall (Sys_gettid);     pid_t pid = Syscall (sys_getpid);     while (1)     {         printf ("Tid =%d, pid=%d\n", Tid, PID);         Sleep (1);     } }

The results are easy to verify.

Note: the-l option in the PS command displays the following information:
LWP: The thread ID, which is the return value of both Gettid () system calls.
NLWP: Number of thread Group threads

And what type of pthread_t is depending on the implementation. For Linux?? NPTL implementation of the current implementation? And, pthread_t type of thread ID, essentially? A process address space? An address.

The traditional process model is described earlier, with only one control thread per process. In the case of POSIX threads: Before creating multithreading, the program is also started with a single control thread in a single process. So there's no difference between a program's behavior and the traditional process. New threads can be created through pthread_create.

(2) Create thread pthread_create function
Prototype: int pthread_create (pthread_t *thread,   //thread identifier         const pthread_attr_t *attr,         //thread property is   usually filled with null         void * (*start_routline) (void *),   //thread callback function        void *arg);          Parameter NULL for callback function                      

The creation of a successful thread ID is set to the memory unit that thread points to. The newly created thread executes from the Start_routline address, which has an untyped pointer parameter arg, and if you need to pass more than one parameter to the Start_routeline function, then you need to put these parameters into a struct, and then the address of the struct is passed in.

Example:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h>  void * Myroute (void *arg) {     printf ("This is Thread one\n");     printf ("pid:%d thread one:%lx\n", Getpid (), pthread_self ()); }  int main (void) {     pthread_t tid;     if (pthread_create (&tid, NULL, Myroute, NULL)! = 0)     perror ("Can ' t create thread"), exit (1);     printf ("pid:%d  main thread:%lx\n", Getpid (), pthread_self ());     Sleep (1);     printf ("return\n"); }

Change it.

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h>  void * Myroute (void *arg) {     while (1)     {         printf ("The IS Thread one\n");         printf ("pid:%d thread one:%lx\n", Getpid (), pthread_self ());     } }  int main (void) {     pthread_t tid;     if (pthread_create (&tid, NULL, Myroute, NULL)! = 0)         perror ("Can ' t create thread"), exit (1);     while (1)     {         printf ("pid:%d  main thread:%lx\n", Getpid (), pthread_self ());         Sleep (1);     }     printf ("return\n"); }

Note: for the second parameter, attr is used to customize a variety of thread properties, it is usually empty so that the thread has a default property, if you need to set the thread properties, the following two functions are used

#include <pthread.h>//Initialize Thread propertiesIntPthread_attr_init (pthread_attr_t *attr);//Destroying thread PropertiesIntPthread_attr_destroy (pthread_attr_t *attr); Its properties have thread attributes: Detach attribute: Detach state = pthread_create_joinable Snatch resource scope: scope = Pthread_scope_system whether to inherit schedule policy Slightly: Inherit scheduler = pthread_inherit_sched scheduling policy () Scheduling policy = Sched_other //Time- sharing scheduling strategy is Sched_other 
                  
                    Scheduling priority: Scheduling 
                    the reserved area between the 0-wire stacks: Guard size = 4096 bytes /// the thread stack address that is primarily used to ensure thread safety itself: STAC K address = 0x40196000 itself specifies the line Cheng size: Stack size = 0x201000 bytes /c8> 
                  

For the detach attribute:

Use the following two functions. They are set separation state and get detach state respectively

int detachstate); pthread_attr_getdetachstate (*detachstate);  

Example

#include <pthread.h> #include <stdio.h> #include <stdlib.h>  pthread_attr_t attr;  void *route (void *arg) {     printf ("route1\n");}  int main (void) {     pthread_t tid;     Pthread_attr_init (&attr);     Pthread_attr_setdetachstate (&attr, pthread_create_detached);     Pthread_create (&tid, &attr, Route, NULL);      int ret;     Pthread_attr_getdetachstate (&attr, &ret);     if (ret = = pthread_create_detached) {         printf ("pthread_create_detached\n");     } else if (ret = = Pthread_create_j oinable) {         printf ("pthread_create_joinable\n");     }      Pthread_attr_destroy (&ATTR); }

Results:

[Email protected]:~/day19$./a . Out pthread_create_detached

(3) The exit Pthread_exit function of the thread
#include <pthread.h>void pthread_exit (void *retval);

The retval parameter is an untyped pointer, similar to a single parameter passed to the startup routine, and be careful not to point it to a local variable. Other threads in the process can access this pointer by calling the Pthread_join function to get the terminating state of the thread.

(4) canceling execution of the thread pthread_cancle function
prototypes int pthread_cancel (pthread_t thread); parameter thread: Thread ID return value: successful return 0; failure return error code

Summary about thread death conditions:

  1 when the thread handler function returns;

2.pthread_exit is called (process is dead after all threads in the process die)

3. The thread was called by another thread to cancel the Pthread_cancel function. (It is worth noting that the cancel thread does not exit immediately, but waits until the system calls to the cancel point.) You can call the Pthread_testcancel (void) function to artificially add a cancel)

thread wait and detach

(5) Thread wait function pthread_join

The reason why a thread wait function is required is because the ① has exited the thread and its space is not released, still within the process's address space. ② creating a new thread does not duplicate the address space of the thread you just exited.

#include <pthread.h>int pthread_join (pthread_t thread, void **value_ptr);

Note here that retval is a level two pointer, because it needs to be modified during the execution of the wait thread death. function does not return until the PID thread dies, returns 0 successfully, and fails to return an error code.

At this point, the calling thread blocks until the specified thread calls Pthread_exit, returns from the boot Journey, or is canceled. Thread threads are terminated with different pthread_join methods.
To the terminating state is different:
1. If the thread thread returns by return, *value_ ptr points to a cell that holds the return value of the thread's function.
2. If the thread thread is called by another thread Pthread_ Cancel exception ends, *value_ ptr points to the cell where the constant pthread_ CANCELED is stored.
3. If the thread thread is called Pthread_exit terminated by itself, *valueptr points to a cell that holds the parameters passed to Pthread_exit.
4. If you are not interested in the terminating state of thread threads, you can pass NULL to the Value_ ptr parameter.

If you are not interested in the return value of a thread, you can set the valude_ptr to null (typically empty). In this case, the call to the Pthread_join function can wait for the specified thread to terminate, but not to get the thread's seed state.

(6) Thread separation function

By default, the newly created thread is joinable, and after the thread exits, it needs to be pthread_join, or the resource cannot be freed, causing a system leak.
If you do not care about the return value of a thread, join is a burden, and this time we can tell the system to automatically release thread resources when the thread exits

int Pthread_detach (pthread_t thread);

It is possible for other threads within a thread group to detach a target thread, or a thread to detach itself:

Pthread_detach (Pthread_self ());

Joinable and separation are conflicting, and a thread cannot be both joinable and detached.

Example:

#include <string.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include < unistd.h> #include <pthread.h>  void *thread_run (void* arg)  {     Pthread_detach (pthread_self ());     printf ("%s\n", (char*) arg);     return NULL; } int main (  void) {     pthread_t tid;     Char str[] = "thread1 run ...";     if (Pthread_create (&tid, NULL, Thread_run, str)! = 0) {          printf ("Create thread error\n");         return 1;     }      int ret = 0;     Sleep (1);     if (Pthread_join (tid, NULL)  = = 0)  {          printf ("Pthread wait success\n");         ret = 0;     }  else {          printf ("Pthread wait failed\n");         ret = 1;     }     return ret; }

linux--Threads

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.