Linus multithreaded Programming (1)

Source: Internet
Author: User
Tags posix

Thread Concept:

a thread is the smallest execution unit of an in-process, independent dispatch. Sometimes called lightweight processes (lightweight process,lwp). A process is an entity in progress, is the basic unit that is dispatched and dispatched independently by the system, the thread does not own the system resources, and has only a bit of resources necessary to run, but it can share all the resources owned by the process with other threads belonging to one process. One thread can create and revoke another thread, which can be executed concurrently between multiple threads in the same process.

How to execute multiple threads in the address space of a process. There are situations where you need to perform multiple control processes simultaneously in a process, where threads come in handy, such as downloading software that implements a graphical interface that needs to interact with users, wait and handle user mouse and keyboard events, and simultaneously download multiple files, waiting for and processing data from multiple network hosts , these tasks require a "wait-and-process" loop that can be implemented in multiple threads, a thread that is specifically responsible for interacting with the user, and several threads per thread responsible for communicating with a network host.

Because multiple threads of the same process share the same address space, the Text Segment, Data Segment are shared , and if you define a function that can be called in each thread, if you define a global variable that can be accessed in each thread, in addition, Each thread also shares the following process resources and environment :

1. File Descriptor Descriptor
2. How each signal is processed (sig_ign, SIG_DFL or? defined signal processing functions)
3. Current working directory
4. User ID and Group ID

But some of the resources are each thread has one copy:

1. Thread ID

2. Context, including values for various registers, program counters, and stack pointers
3. Stack space
4. errno variables
5. Signal Shielding Word
6. Scheduling priority

The line libraries function we are going to learn is defined by the POSIX standard, known as POSIX thread or pthread. The Linux thread function is located in the Libpthread shared library, so the -lpthread option is added at compile time .


Line Program Control system

A. Thread creation

Synopsis:

#include <pthread.h>

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

Return value: successful return 0, Failure returns error number. previously learned system functions are successful return 0, failed to return 1, and the error number is stored in the global variable errno, the Pthread library function is returned by the return value of the error number, although each thread also has a errno, but this is to be compatible with other function interfaces, The Pthread library itself does not use it and returns the error code with a clearer return value.

After calling Pthread_create () in a thread to create a new thread, the current thread returns from Pthread_create () to continue execution, and the code executed by the new thread is passed to the Pthread_create function pointer Start_ Routine decided. The Atart_routine function receives a parameter that is passed to it by the ARG parameter of the pthread_create, the type of the parameter is void*, the meaning of this pointer is the same as the caller's own definition of the return of the Start_routine, the thread exits, Other threads can call Pthread_join to get the Start_routine return value, similar to the parent process calling wait () to get the child process exit status.

Since the Pthread_create error code is not errno, so you cannot print the error message directly with Perror (), you can first use Strerror (errno) to convert the error code to the error message in print.


Code://PTHREAD.C

<span style= "FONT-SIZE:14PX;" > #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <errno.h>pthread_t Tid;void *thread_run (void *_val) {printf ("%s,pid:  %d,tid is:%u\n", (char*) _val, (int) getpid (),    //(unsigned Long long) pthread_self (); tid); return NULL;} If create success, return 0//else return Errnoint main () {int err = pthread_create (&tid, NULL, thread_run, NULL); if (E RR! = 0) {printf ("Create Thread is failed! Info is:%s\n ", Strerror (errno)); exit (err); printf ("Man Pthread was run, PID is:%d,tid is:%u\n", (int) getpid (), (unsigned long Long) pthread_self ()); sleep (3); return 0; }</span>

compilation: Gcc-o pthread pthread.c-lpthread

Result: Man pthread is run, PID Is:18442,tid is:3077609152
(null), Pid:18442,tid is:307760625
... (Sleep (3))



B. Thread termination

If you need to terminate only one process without terminating the entire process, there are three ways to do this:
① return from the thread function. This method does not apply to the main thread, and return from the main function is equivalent to calling exit.
② one thread can call Pthread_cancel to terminate another process in the unified process.
③ thread is happy to call Pthread_exit to terminate itself.

#include <pthread.h>

void Pthread_exit (void *retval);
RetVal is the void* type, and the same as the use of the thread function return value, other threads can call Pthread_join to get this pointer. It is important to note that the Pthread_exit or return pointer points to a memory cell that must be global or allocated with malloc and cannot be allocated on the stack of the thread function, because the function has exited when other threads get the return pointer.


after the thread terminates, its terminating state is retained until the other thread calls Pthread_join to get its state. However , a thread can also be set to the detach state, which, once terminated, reclaims all the resources it occupies without leaving the terminating state. You cannot call Pthread_join on a thread that is already in the detach state, and such a call will return einval. Call Pthread_join or Pthread_detach for a thread that is not yet detach. This thread is set to the detach state, that is, you cannot call two pthread_join on the same thread, or if you have already calling Pthread_detach on a thread can no longer call pthread_join.


Code://pthread_join

<span style= "FONT-SIZE:14PX;" > #include <stdio.h> #include <stdlib.h> #include <pthread.h>void *pthread_run1 (void *arg) {printf ("Thread_run1 return \ n"); return (void*) 1;} void *pthread_run2 (void *arg) {printf ("thread_run2 exit!\n");p Thread_exit ((void*) 2);} void *pthread_run3 (void *arg) {while (1) {printf ("Thread_run was running, wait for cancel!\n"), and Sleep (3);} return NULL;} int main () {pthread_t tid;void *_retval;pthread_create (&tid, NULL, PTHREAD_RUN1, NULL);p Thread_join (Tid, &_ retval);p rintf ("thread_run1 return, Thread ID is:%u, return code is:%d\n", (unsigned Long) tid, (int) _retval);p Thread_cre ATE (&tid, NULL, PTHREAD_RUN2, NULL);p Thread_join (tid, &_retval);p rintf ("Thread_run2 exit, Thread ID is:%u, exit Code is:%d\n ", (unsigned Long) tid, (int) _retval);p thread_create (&tid, NULL, PTHREAD_RUN3, NULL); Sleep (3);p Thread_ Cancel (tid);p thread_join (tid, &_retval);p rintf ("Thread_run3 return, Thread ID is:%u, return code is:%d\n", ( unsigned long) tid, (int) _retval); return 1;} </span>


Compilation: Gcc-o Pthread_join Pthread_join.c-lpthread

Operation Result:

THREAD_RUN1 return
THREAD_RUN1 return, thread ID is:3077827440, return code is:1
Thread_run2 exit!
THREAD_RUN2 exit, Thread ID is:3077827440, exit code Is:2
Thread_run is running, wait for cancel!

Sleep (3)
THREAD_RUN3 return, thread ID is:3077827440, return code is: 1

-------------------------------------------------------------------------------------

The value of the constant pthread_canceled in Linus's Pthread library is-1.

C. Thread Waits

int Pthread_join (pthread_t pthread, void **retval);
① if thread returns by return, the cell to which value_ptr points is the return value of the thread's function.
② If the thread is terminated by another thread pthread_cancel, the unit that value_ptr points to is usually pthread_canceled.
③ If the thread is terminated by its own invocation of Pthread_exit (), value_ptr points to a cell that holds the arguments passed to Pthread_exit (). If the terminating state of thread threads is not interesting, you can pass NULL to the VALUE_PTR parameter.

About Detaching Threads

At any point in time, the thread is either associative (joinable) or detached (detached). A thread that can be combined can be withdrawn by another thread and killed by its resources. Its memory resource is not freed until it is reclaimed by another thread. Instead, a disconnected thread cannot be recycled or killed by other threads, and its memory resources are automatically freed by the system when it terminates.

By default, threads are created to be combined. In order to avoid memory leaks, each of the bonded threads should either be shown to be recycled, called pthread_join, or separated by calling the Pthread_detach function.

If a binding thread ends up running but not being join, its state is similar to the zombie process in progress, that is, some of the resources are not recycled, so the creator should call Pthread_join to wait for the thread to run and get the thread's exit code. Reclaim its resources.

Since the call to Pthread_join, if the thread does not end up running, the caller will be blocked, in some cases we do not want this. For example, in a Web server, when the main thread creates a child thread for each new connection request, the main thread does not want to block because of the call to Pthread_join (because the incoming connection request continues to be processed), you can add code to the child thread Pthread_ Detach (Pthread_self ()) or parent thread calls Pthread_detach (thread_id) (non-blocking, can be returned immediately)


Code://PTHREAD_DETACH.C

<span style= "FONT-SIZE:14PX;" > #include <stdio.h> #include <stdlib.h> #include <pthread.h>void *pthread_run (void *arg) {pthread _detach (Pthread_self ());p rintf ("Pthread is running!\n"); return NULL;} int main () {pthread_t tid;int ret = pthread_create (&tid, NULL, Pthread_run, "thread run!"); if (ret! = 0) {printf ("Thread Create failed! \ n "); exit (1);} int _val = 0;sleep (3), if (0! = Pthread_join (tid, NULL)) {printf ("Pthread wait failed!\n"); _val = 1;} else{printf ("Pthread wait success!\n"); _val = 0;} return _val;} </span>

Compile:

Gcc-o Pthread_detach Pthread_detach.c-lpthread

Operation Result:

Pthread is running!

Sleep (3)
Pthread wait failed!

------------------------------------------------------------------------

If not added Pthread_detach (pthread_self ());

Wait success!

This sets the state of the child thread to detached (detached) so that when the thread finishes running, it automatically releases the put all resources.

So the main thread wait failed!

--------------------------------------------------------------------------------------------------------------- --

In general, after a thread terminates, its terminating state is retained until the other thread calls Pthread_join to get its state toTo stop. But the thread can also be set to the detach state, so that once the thread terminates, it reclaims all the resources it occupies.The terminating state is not preserved. You cannot call Pthread_join on a thread that is already in the detach state, and such a call willreturns EINVAL. Calling Pthread_join or Pthread_detach on a thread that is not yet detach can take the threaddetach State, which means that you cannot call two pthread_join on the same thread, or if you have already tuned a threadwith the Pthread_detach, you can no longer call pthread_join.













Linus multithreaded Programming (1)

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.