(10) Learn the Unix Environment Advanced Programming (APUE) line program control system

Source: Internet
Author: User
Tags bitwise posix

.

.

.

.

.

We used the default property when we created the thread, and this chapter mainly discusses the properties of the custom thread.

Using default properties basically solves most of the problems encountered, so custom attributes are used less in actual projects.

1. Thread Properties

Apue The third edition of the P341 table has properties that can be used to limit the maximum number of threads a process can create, but macros that limit the number of threads do not have to be taken too seriously, because in the last blog post we said a thread Cheng Nen the number of threads created is affected by many factors, not necessarily with these macro values.

Thread properties are represented using the pthread_attr_t type.

1#include <stdio.h>2#include <stdlib.h>3#include <pthread.h>4#include <string.h>5 6 Static void*func (void*p)7 {8Puts"Thread is working.");9 Ten Pthread_exit (NULL); One } A  - intMain () - { the pthread_t tid; -     interr, I; - pthread_attr_t attr; -  +Pthread_attr_init (&attr); -     //Modify the stack size for each thread +Pthread_attr_setstacksize (&attr,1024x768*1024x768); A  at      for(i =0; ; i++) -     { -         //test How many threads the current process can create -Err = Pthread_create (&tid,&attr,func,null); -         if(ERR) -         { infprintf (stderr,"pthread_create ():%s\n", Strerror (err)); -              Break; to         } +  -     } the  *printf"i =%d\n", i); $     Panax NotoginsengPthread_attr_destroy (&attr); -  theExit0); +}

The chestnut above modifies the size of the stack space allocated for each thread through the thread's properties, so that the number of threads created differs from the default.

The thread properties are initialized using the Pthread_attr_init (3) function and then destroyed using the Pthread_attr_destroy (3) function.

Thread properties can not only set the size of the thread's stack space, but also create separate threads and so on.

2. Mutex Properties

The mutex property is represented using the pthread_mutexattr_t type, which, like the thread properties, is initialized before use and is destroyed.

The Pthread_mutexattr_init (3) function initializes the property of the mutex, which is similar to the properties of the thread.

1pthread_mutexattr_getpshared, pthread_mutexattr_setpshared-Get and2        SetThe process-Shared Attribute3 4#include <pthread.h>5 6 intPthread_mutexattr_getpshared (Constpthread_mutexattr_t *7Restrictattr,int*restrict pshared);8 9 intPthread_mutexattr_setpshared (pthread_mutexattr_t * attr,Ten        int pshared);

The P in the function name refers to the process, the function of which is to set whether the thread's properties can be used across processes. This is a bit of a mess, how can thread properties be used across processes? Don't worry, let's look at the Clone (2) function first.

1Clone, __clone2-Create a child process2 3 #define_gnu_source4#include <sched.h>5 6 intCloneint(*fn)(void*),void* child_stack,7           int Flags,void* arg, ...8           /*pid_t *ptid, struct User_desc *tls, pid_t *ctid*/);

Clone (2) The flags of the process if Clone_files is set up, the parent-child process shares the file descriptor, and the normal file descriptor is shared between threads because multithreading is run within the same process's address space.

Although the Clone (2) function is described as creating a subprocess, in fact, if the flags property is set to be extremely detached (all resources are exclusive), it is equivalent to creating a child process;

If the Flags property is set to an extreme approximation (a variety of resources are shared), it is equivalent to creating a sibling thread. So there is no concept of process for the kernel, only the thread concept. Whether you create a process or a thread does not affect the kernel scheduling.

If you need to create a "thing" that shares a subset of resources with the current thread, and a portion of the resources, you can use the Clone (2) function to create a "thing" that is neither a thread nor a process, because processes and threads are inherently fuzzy concepts for the kernel.

Now I can understand why it says pthread_mutexattr_setpshared (3) function is to set whether the properties of a thread can be used across processes?

Mutex is divided into four kinds, different mutual exclusion in different situations when the effect is different, "Apue" the third edition P347 Figure 12-5 illustrates this phenomenon, LZ copy it here.

Mutex type Re-lock when not unlocked Unlock when not in use Unlock when unlocked
Pthread_mutex_normal (General) Dead lock Not defined Not defined
Pthread_mutex_errorcheck (Error checking) return error return error return error
Pthread_mutex_recursive (Recursive) Allow return error return error

Pthread_mutex_default

(By default, this is what we usually use)

Not defined Not defined Not defined

Table 1 Mutex type behavior

LZ explains what the description on the header means:

1) not unlocked when re-lock: The current mutex has lock, again lock the case;

2) Unlock when not in use: someone else locks the case you unlocked;

3) Unlocked when unlocked: The current mutex has been unlock, again unlock the situation;

3. Re-entry

The first time you see re-entry is at the signal stage.

If a function can be called safely by multiple threads at the same point in time, it is called a thread-safe function.

The POSIX standard requires that after the thread standard has been established, all libraries must support threaded security, if thread safety is not supported, add the _unlocked suffix to the function name, or publish a function that supports thread safety, and the function name is to add the _r suffix.

We've seen a lot of functions with _r suffixes in the Man Handbook.

4. Thread-specific data

is for some data to support multi-threaded concurrency improvements. The most typical is that Errno,errno was originally a global variable and has now become a macro definition.

Let's pre-compile the errno and look at it.

1 #include <errno.h>23 errno;

1 gcc -E errno.c22"errno.c"23 4 (*__errno_location ()); 5 >$

5. Cancellation of Threads

As we said in the previous blog post, the Pthread_cancel (3) function simply made a cancellation request and cannot force the thread to be canceled.

The cancellation of a thread is divided into two situations: Allow cancellation or disallow cancellation.

Pthread_cancel (3) after the cancellation request is made, whether or not the cancellation is allowed is determined by the thread being requested to cancel.

Not allowed to cancel there's nothing to say, let's talk about permission to cancel.

There are two scenarios of allowing cancellation: asynchronous Cancel and deferred cancel (default)

1) Asynchronous Cancel: is the kernel operation mode, here does not explain.

2) Postpone cancel: Postpone to the cancel point before responding to the cancel operation. The cancellation point is actually a function, and the code that cancels the point when the cancellation request is received is not executed.

The third edition of Apue, P362 figure 12-14, is a system call that can cause blocking, both of which are defined by POSIX as a certain existence cancellation point. P363 Figure 12-15 is a POSIX-defined optional cancellation point that is actually a cancellation point to see the platform-specific implementation.

Why take a deferred cancellation strategy instead of receiving a request for immediate cancellation anywhere? Let's start with a chestnut to illustrate the problem, let's look at the pseudocode below:

1 Thr_func ()2 3 {4 5p =malloc();6 7-------------------------->A cancellation request was received8 9-------------------------->pthread_cleanup_push ();-> Free(p);//not cancel point, continue executionTen  OneFD1 = open ();//is to cancel the point and respond to the cancel action before the cancel point executes A  --------------------------->pthread_cleanup_push ();->Close (FD1); -  theFD2 =open (); -  --------------------------->pthread_cleanup_push ();->Close (FD2); -  + pthread_exit (); -  +}

A cancellation request may be received at any time when the thread execution function is running, assuming that the above function has just been dynamically allocated a memory using the malloc (3) function and has received a cancellation request when the hook function is not available, and if the immediate response to this cancellation request causes a memory leak. While the macro Pthread_cleanup_push of the hook function is not a cancellation point, the cancellation request will be postponed to continue working. After it has mounted the hook function and continues to run to the open (2) function, due to the open (2) function when a valid cancellation point, so in response to this cancellation request, the thread is canceled and through the hook function to release the above malloc (3) Requested space. This is the most obvious effect of postponing cancellation.

The role of the Pthread_setcancelstate (3) function is to modify the cancellation state of a thread, which can be set to either canceled or non-canceled.

The Pthread_setcanceltype (3) function is used to modify the cancellation type, that is, you can select asynchronous cancel and postpone cancel.

The function of Pthread_testcancel (3) is to place the cancellation point artificially. If a thread starts on a crazy math operation for 10 minutes without invoking any function, the thread cannot respond to cancellation, so that the thread can respond to cancellation by placing the cancellation point artificially.

6. Threads and Signals

Figure 1 Thread-level signal bitmap

In the previous blog post that discussed the signal, LZ has drawn a sketch of the signal processing process, which simply draws the standard signal of a thread into two bitmaps in that image. In fact, each thread level holds a mask bitmap and a padding bitmap, and each process level holds a padding bitmap without a mask bitmap. From the kernel state back to the user state, the current thread first with its own mask bitmap and process-level padding do bitwise AND (&) operation, if there is a signal to be processed, and then use their own mask bitmap and their own padding bitmap to do the bitwise AND operation, and then processing the corresponding signal.

So in fact, which thread is dispatched, which thread responds to the process-level signal.

This shows that the threads can also signal each other.

1 pthread_kill- send a signal to a thread23 #include <signal.h>4  5intthreadint   sig); 6 7 Compile and link with-pthread.

The function of the Pthread_kill (3) is to signal the thread phase, andthread indicates which signal to send, and which is thesig .

Since this function is very simple to use, here LZ will not put the chestnut paste out, we have to write their own to try it.

The Pthread_sigmask (3) function acts as an artificial intervention at the thread-level mask bitmap. Like the Sigsetmask (3) function, let's try it yourself.

7. Threading and Fork

This section is mainly about fork (2) on different platforms to achieve ambiguity.

In the development of fork, there are two major camps, one for the use of copy-on-write technology, and the other to use a strategy similar to Vfork (2).

Both of these strategies have been discussed in the previous blog post discussing the process relationship, and the children's shoes are interesting to read the descriptions on their own, so there's not much to be done about it.

8. Threading and I/O

This section mainly introduces the next Pread (2) and the Pwrite (2) function, these two functions are not used much in practice, interested in children's shoes to read the book or look at the instructions in the Man manual, there is no too much discussion. If you have any questions, you can leave a comment in the comments.

This is where the POSIX standard threads are introduced. The standard for *nix platform threads is not only POSIX, but also standards like OpenMP define different ways of threading.

9.OpenMP Standard

We use the OpenMP standard to write a Hello world program.

1#include <stdio.h>2#include <stdlib.h>3#include <omp.h>4 5 intMain ()6 {7 #pragmaOMP parallel Sections8 {9 #pragmaOMP sectionTenprintf"[%d]:hello\n", Omp_get_thread_num ()); One #pragmaOMP section Aprintf"[%d]:world\n", Omp_get_thread_num ()); - } -  theExit0); -}

The OpenMP standard multithreading is implemented using the # preprocessing tag, which needs to be added with the-FOPENMP parameter when compiling with GCC.

 Make Hello cc -fopenmp-wall    hello.c   -o hello>$./hello[0]:hello[  1]:world>$./hello[1]:world[0]:hello >$

As you can see from the running results above, the threads have been created and the competition has already occurred.

GCC supports the OpenMP standard from more than 4.0 versions.

Since the OpenMP standard is not introduced in "Apue", we do not have much discussion here, and interested partners can go to http://www.openmp.org to learn more.

(10) Learn the Unix Environment Advanced Programming (APUE) line program control system

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.