Thread end resource release thread end

Source: Internet
Author: User


When a thread is created, the system allocates some resources to the thread. What we can see is the thread Descriptor and thread stack. There will be more complex information maintained by the system. When a thread is created, the kernel always maintains some resources for it. Ideally, after the thread finishes running, it releases system resources and process resources, including the memory occupied by the return value of the thread, thread stack, and register status, for later use.


Three methods to release resources after thread execution is completed:

Using these methods, we can avoid the situation where the system resources cannot be released when the thread exits:

  1. Pthread_join. The prototype of this function is pthread_join (pthread_t thread, void ** value_ptr). It blocks the thread that calls the function and waits for the specified thread to exit. Pthread_join is successfully called only when the thread is accessible.
  2. Pthread_detach. This function can change the accessible attributes of a thread and change it to the separation mode. When the thread is in the separation mode, it indicates that we do not care about the return value of the thread. After the worker thread is executed, it will exit and the kernel will release the resources occupied by the thread.
  3. Set the thread property structure pthread_attr_t to be separated, such as pthread_attr_init (& ATTR); pthread_attr_setdetach (& ATTR, pthread_create_detached), and use this thread property object to participate in the pthread_create Function, the created threads are separated.
The meaning of using the separation thread is as follows:

Identify leaks

If you create a thread that can be joined but forget to join it, its resources or private memory will be stored in the process space and never be recycled. Must be connected
Otherwise, it may cause serious memory leakage.

For example, a thread on Red Hat Enterprise Linux (RHEL4) needs a 10 MB stack, which means that if it is not connected, there will be at least
10 MB memory leakage. Suppose you design a program in Manager-worker thread mode to process incoming requests. Then, you need to create more and more worker threads to execute various tasks and finally terminate these threads. If they are connectable threads and you have not calledpthread_join()After the thread is terminated, each generated thread will leak a large amount of memory (at least each stack
10 MB ). As more and more worker threads are created and terminated without connection, the amount of memory leaked continues to increase. In addition, the process cannot create a new thread because there is no memory available for creating a new thread.

Listing 1 shows the serious memory leakage that occurs when you forget to join a thread that can be joined. You can also use this code to check the maximum number of threads that can coexist in a process space.

#include<stdio.h>#include<pthread.h>void run() {   pthread_exit(0);}int main () {   pthread_t thread;   int rc;   long count = 0;   while(1) {      if(rc = pthread_create(&thread, 0, run, 0) ) {         printf("ERROR, rc is %d, so far %ld threads created\n", rc, count);         perror("Fail:");         return -1;      }      count++;   }   return 0;}

In list 1pthread_create()Create a new thread with the default thread attributes. By default, new threads can be joined. It creates new connectable threads until a fault occurs. Then output the error code and cause.

When you use the following command to compile the code in Listing 1 on Red Hat Enterprise Linux Server 5.4:[root@server
~]# cc -lpthread thread.c -o thread
, You will get the results shown in Listing 2.

List 2. Memory leakage results

[root@server ~]# ./thread
ERROR, rc
is 12, so far 304 threads created

Fail:: Cannot
allocate memory

It cannot create more threads after the Code creates 304 threads. The error code is12, Which means no more memory is available.

As shown in lists 1 and 2, although a thread can be joined is generated, it is not connected. Therefore, each terminated thread can still occupy process space and leak process memory.

A posix thread on RHEL has a private stack of 10 MB. In other words, the system allocates at least 10 MB of dedicated storage for each pthread. In our example, 304 threads are created before the process is stopped; these threads occupy
304*10 MB memory, totaling about 3 GB. The virtual memory size of a process is 4 GB, of which 1/4 of the process space is reserved for the Linux kernel. In this way, 3 GB of memory space is available for users. Therefore, 3 GB memory is consumed by dead threads. This is a serious memory leak. And it's easy to understand why it happened so quickly.

To fix the leakage, you can add code to callpthread_join()This method can be used to connect each thread that can be joined.

Thread termination method:

1) The main thread can use the pthread_join function to wait for the end of the sub-thread. The pthread_join () function will wait for the end of the specified thread, that is, the main thread will block the sub-thread, if the sub-thread is not completed, the main thread will never execute the program under phread_join. The program is as follows: # include <stdio. h> # include <pthread. h> void pthread_1 () {printf ("I am the child !! \ N "); sleep (2); printf (" I am exit !! \ N ") ;}void main () {pthread_t tid; void * tret; pthread_create (& tid, null, & pthread_1, null); pthread_join (TID, & tret ); printf ("thread exit with code % d \ n", (INT) tret); exit (0);} 2) the main thread stops the sub-thread from canceling in POSIX thread in two states: immediate cancellation and delayed cancellation. Immediate cancellation is after pthread_cancel, which does not manage what the thread is doing, terminate this thread immediately, and the delay is canceled after pthread_cancel. The thread continues to run until a "cancelpoint function" is encountered. The system defaults to the delay cancellation. If you want to end the thread, there are several methods. the thread is set to cancel pthread_setcanceltype (pthread_cancel_asynchronous, n Ull); the program is as follows # include <stdio. h> # include <unistd. h> # include <pthread. h> # include <sys/types. h> void pthead_1 () {pthread_setcanceltype (pthread_cancel_asynchronous, null); While (1) {printf ("I am the child \ n"); usleep (10000 );}} void main () {pthread_t pthread_id; pthread_create (& pthread_id, null, & pthead_1, null); sleep (2); pthread_cancel (pthread_id ); printf ("I make the child exit !! \ N "); pthread_exit (0);} B. add some call to cancel the point function in your thread while (1) {// sleep (1) or pthread_testcancle ();}

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.