Home>

When we were writing Linux services,Linux multithreading technology is often used to improve program performance

Some small knowledge of multithreading:

An application can start several threads.

A thread (lightweight process, lwp) is the smallest unit of program execution.

Generally, the simplest program has at least one thread.Is the program itself,That is the main function (a single-threaded process can simply be considered a process with only one thread)

Blocking one thread does not affect the other thread.

Multi-threaded processes can use system CPU resources as much as possible.

1 create a thread

Let's start with the simple code of creating a thread in a process.Then slowly go deeper.

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
void * func (void * arg)
{
 printf ("func run ... \ n");
 return null;
}
int main ()
{
 pthread_t t1;
 int err=pthread_create (&t1, null, func, null);
 if (err!=0)
 {
  printf ("thread_create failed:%s \ n", strerror (errno));
 } else {
  printf ("thread_create success \ n");
 }
 sleep (1);
 return exit_success;
}
int pthread_create (pthread_t * thread, const pthread_attr_t * attr, void * (* start_routine) (void *), void * arg);

Inside the main function we call the above function to create a thread.

Function parameters:

First parameter:pthread_t represents the unique identifier of the creating thread,Is a structure,After we need to create it,Pass the pointer of this structure.

The second parameter:pthread_attr_t, represents some configuration to create this thread,Such as the size of the allocation stack and so on.. Generally, we can fill in null, which represents the default configuration of creating threads.

The third parameter:the address of a function,When creating a thread,Would call this function,The return value of the function is void *, and the parameter of the function is also void *, the general format is likevoid * func (void * arg) ()

Fourth parameter:represents the parameter passed by calling the third function

Function return value:

The function successfully returns 0. If it is not equal to 0, it means that the function call failed.Strerror (errno) can print out the specific error.

Note:each thread has a copy of errno, different threads have different errno

Finally compiled by gcc

gcc 1createthread.c -c -o 1createthread.o
gcc 1createthread.o -o thr1 -lpthread

When compiling, you need to add -lpthread to link the libpthread.so dynamic library, otherwise you will be prompted that the function cannot be found

Function call returns results

Question:Why call the sleep function

Answer:It may be that the newly created thread has not run to the printing method main thread.And the main thread ends,All threads will end.

2 threads hang

Sometimes we create another thread in one thread,The main thread waits until the created thread returns,The main thread does not exit until the return value of the thread is obtained.This time you need to use thread suspension.

int pthread_join (pthread_t th, void ** thr_return) ;.

The pthread_join function is used to suspend the current thread,Until the thread specified by th terminates.

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
void * func (void * arg)
{
 int i=0;
 for (;i<5;i ++)
 {
  printf ("func run%d \ n", i);
  sleep (1);
 }
 int * p=(int *) malloc (sizeof (int));
 * p=11;
 return p;
}
int main ()
{
 pthread_t t1, t2;
 int err=pthread_create (&t1, null, func, null);
 if (err!=0)
 {
  printf ("thread_create failed:%s \ n", strerror (errno));
 } else {
  printf ("thread_create success \ n");
 }
 void * p=null;
 pthread_join (t1,&p);
 printf ("Thread exited:code =%d \ n", * (int *) p);
 return exit_success;
}

Function execution result

Our main function has been waiting for the created thread to finish executing,And got the return value of the end of the thread execution

3 thread termination

The exit () function when the process terminates, so what is the thread termination?

Three cases of thread termination:

The thread just returns from the start function,The return value is the exit code of the thread.

Threads can be cancelled by other threads in the same process.

The thread calls pthread_exit.

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
void * func (void * arg)
{
 int i=0;
 while (1)
 {
  if (i == 10)
  {
   int * p=(int *) malloc (sizeof (int));
   * p=11;
   pthread_exit (p);
  }
  printf ("fun run%d \ n", i ++);
  sleep (1);
 }
 return null;
}
int main ()
{
 pthread_t t1, t2;
 int err=pthread_create (&t1, null, func, null);
 if (err!=0)
 {
  printf ("thread_create failed:%s \ n", strerror (errno));
 } else {
  printf ("thread_create success \ n");
 }
 void * p=null;
 pthread_join (t1,&p);
 printf ("Thread exited:code =%d", * (int *) p);
 return exit_success;
}
void pthread_exit (void * arg);

The parameters of the pthread_exit function are the same as when the return of a normal thread ends.Will be obtained by the main thread waiting for it to end.

Function running result:

4 thread separation

int pthread_detach (pthread_t th);

The pthread_detach function leaves the thread in a detached state.

If you don't wait for a thread,Also not interested in the return value of the thread,You can set this thread to be detached.Let the system automatically recycle the resources it occupies when the thread exits.

A thread cannot call pthread_detach by itself to change itself to a detached state.Pthread_detach can only be called by other threads.

5 thread canceled

int pthread_cancel (pthread_t th);
</pre>
</div>
<p>
The pthread_cancel function allows one thread to cancel another thread specified by th.
</p>
<p>
Function succeeded,Returns 0, otherwise returns non-zero.
</p>
<div>
<pre>
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
void * func1 (void * arg)
{
 while (1)
 {
  printf ("fun run ... \ n");
  sleep (1);
 }
 return null;
}
int main ()
{
 pthread_t t1;
 if (pthread_create (&t1, null, func1, null)!=0)
 {
  printf ("thread_create failed:%s \ n", strerror (errno));
  return -1;
 }
 sleep (5);
 pthread_cancel (t1);
 pthread_join (t1, null);
 return exit_success;
}

Function execution result:

Above we said that the second parameter to create a thread function pthread_create,Used to determine some initialization state of the creation thread,Here we give an example,Once a thread is created, it is a thread in a separate state (

The concept of pthread_detach function was introduced above,You can use pthread_attr_t to specify the thread attribute as detach when creating a thread, without modifying the thread attribute after creation.

)

The first piece of code:

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
void * func (void * arg)
{
 int i=0;
 for (;i<5;i ++)
 {
  printf ("func run%d \ n", i);
  sleep (1);
 }
 int * p=(int *) malloc (sizeof (int));
 * p=11;
 return p;
}
int main ()
{
 pthread_t t1;
 pthread_attr_t attr;//Declares a structure of attr
 pthread_attr_init (&attr);//Init structure
 pthread_attr_setdetachstate (&attr, pthread_create_detached);//Set the thread as a detached thread
 int err=pthread_create (&t1,&attr, func, null);
 if (err!=0)
 {
  printf ("thread_create failed:%s \ n", strerror (errno));
 } else {
  printf ("thread_create success \ n");
 }
 pthread_attr_destroy (&attr);
 pthread_join (t1, null);
 printf ("The main thread exited \ n");
 return exit_success;
}

pthread_attr_t is the structure of the parameters we want to pass in,Generally stated steps are

1, declare a pthread_attr_t object

2. The function pthread_attr_init initializes the attr structure.

3, set some properties of the thread,For example, the pthread_attr_setdetachstate function is to set the thread to a normal state or a detached state when it is created.

4, function pthread_attr_destroy releases attr memory space

pthread_attr_setdetachstate sets the thread attribute to one of two legal values:

value

Description

pthread_create_detached

Set the thread to detached state

pthread_create_joinable

Set the thread to a normal state

The result of the above function:

Because threads are detached,So the pthread_join hang will fail,The main thread ends quickly,The process is over.The created thread has not had time to run

Thread synchronization

Sometimes we have such problems when processing multiple orders to reduce inventory.Two threads enter a piece of code at the same time to query the inventory first,Both found out that there was one item left,After the first thread has used this inventory,Change the inventory to 0, but the second thread also found out that it was 1, so he also thinks that there is inventory,

At this time, the operation will cause unexpected events.The inventory has become negative! !! So you need to use thread synchronization at this time! !!

First look at the code to see the effect:

#include<pthread.h>
#include<stdio.h>
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
void * func (void * arg)
{
 int threadno=* (int *) arg;
 int i=0;
 for (;i<10;i ++)
 {
  printf ("%d thread%d \ n", threadno, i);
  sleep (1);
 }
 return null;
}
int main ()
{
 pthread_t t1, t2;
 int i1=1, i2=2;
 pthread_create (&t1, null, func,&i1);
 pthread_create (&t2, null, func,&i2);
 pthread_join (t1, null);
 pthread_join (t2, null);
 printf ("The main thread exited \ n");
 return exit_success;
}

Function running result:

You can see that the two threads are scrambling to deal with each other irregularly.If this code is deducting inventory, it's done! , So we have to lock this code,Only one thread can enter the operation at a time!

First on the code:

#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
pthread_mutex_t mutex=pthread_mutex_initializer;
void * func (void * arg)
{
 pthread_mutex_lock (&​​mutex);//Lock the mutex, other threads will hang after entering,Know this lock is unlocked
 int threadno=* (int *) arg;
 int i=0;
 for (;i<10;i ++)
 {
  printf ("%d thread%d \ n", threadno, i);
  sleep (1);
 }
 pthread_mutex_unlock (&​​mutex);
 return null;
}
int main ()
{
 pthread_t t1, t2;
 int i1=1, i2=2;
 pthread_create (&t1, null, func,&i1);
 pthread_create (&t2, null, func,&i2);
 pthread_join (t1, null);
 pthread_join (t2, null);
 printf ("The main thread exited \ n");
 return exit_success;
}

Function running result:

You can see that the second thread enters and then finishes running.After unlocking mutex, the first thread can run in the method! Otherwise it will hang,Wait until the lock is unlocked!

pthread_mutex_initializer is a macro definition that initializes a quick lock.

pthread_mutex_t mutex=pthread_mutex_initializer;

Lock and unlock function:

int pthread_mutex_lock (pthread_mutex_t * mutex);
int pthread_mutex_unlock (pthread_mutex_t * mutex);

to sum up

c
  • Previous Analysis of mysql index
  • Next Two solutions to the lack of Oracle table space