C language Multithreading
Multithreading is a specialized form of multi-tasking, multi-tasking allows let the computer run two or more programs. In general, two types of multitasking: process-based and thread-based .
- Process-based multitasking is the concurrent execution of the program.
- Based on multi-task processing thread is executed concurrently fragment of the same program.
Multi-threaded program contains two or more parts that can run concurrently. Each part of such a program is called threads, each defining a single execution path.
This tutorial assumes you are using the Linux operating system, we want to use POSIX write multithreaded C ++ programs. API POSIX Threads may be provided or Pthreads available on many types Unix POSIX system, such as FreeBSD, NetBSD, GNU / Linux, Mac OS X, and Solaris.
Create a thread
The following program, we can use it to create a POSIX threads:
#include <pthread.h>
pthread_create (thread, attr, start_routine, arg)
Here, pthread_create creates a new thread and make it executable. The following is a description of the parameters:
参数 | 描述 |
---|---|
thread | 指向线程标识符指针。 |
attr | 一个不透明的属性对象,可以被用来设置线程属性。您可以指定线程属性对象,也可以使用默认值 NULL。 |
start_routine | 线程运行函数起始地址,一旦线程被创建就会执行。 |
arg | 运行函数的参数。它必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。 |
When you create a thread successfully, the function returns 0, if the return value of 0 indicates that failed to create thread.
Terminate the thread
Use the following procedure, we can use it to terminate a POSIX threads:
#include <pthread.h>
pthread_exit (status)
Here, pthread_exit used to explicitly exit a thread. Typically, pthread_exit () function is called when there is no need to continue the work after the completion of the thread.
If the main () is the thread that it created before the end, and () to exit through pthread_exit, the other threads will continue to execute. Otherwise, they will () is automatically terminated at the end of main.
Connection and separation thread
We can connect or separate threads using the following two functions:
pthread_join (threadid, status)
pthread_detach (threadid)
pthread_join () subroutine obstruct the calling program until the specified threadid thread terminated. When a thread is created, it's an attribute defines whether it is connected (joinable) or detachable (detached). Defined only create threads that can be connected can be connected. If a thread is created is defined as separable, it can never be even. pthread_join () function to wait for the completion thread.
note
pthread library is not Linux system default library, you need to use the library to connect libpthread.a, using pthread_create thread is created, compiled in to add -lpthread parameters :
gcc createThread.c -lpthread -o createThread.o
./createThread.
Test 1-threaded programming pass instance no parameters
// thread-based concurrent programming // Test_1 CreateThread #include <stdio.h> #include <pthread.h> / * * the pthread library is not Linux system default library, you need to use the library libpthread.a connection, * using pthread_create when a thread is created, compiled in to add -lpthread parameters: * gcc -o createThread.o createThread.c -lpthread * ./createThread.o * plus the top two after the compilation is successful, and outputs the result * * / #define NUM_THREADS 5 run function threads // void * printHello (void * Arg) { the printf ( "the Hello, World of C in the thread \ n-!"); return 0; } int main () { int I; int RET; // define id variable thread, the plurality of array variables pthread_t TIDS [num_threads]; for (I = 0; I <num_threads; I ++) { // parameters are: thread id created thread parameters, function calls, arguments passed RET = pthread_create (& TIDS [i], NULL, printHello, NULL); IF (RET = 0!) { Printf ( "pthread_create error: ERROR_CODE = \ the n-"); } } // after launch and other threads, processes until the end pthread_exit (NULL); return 0; } / * * output in the CLion (Ubuntu) is Hello, World of thread C in! the Hello, World of the Thread in C! the Hello, World of the Thread in C! the Hello, World of the Thread in C! the Hello, World of the Thread in C! * * /
Test 2 of simple parameter passing thread concurrent programming examples
// thread-based concurrent programming, transmitted to the thread parameters. 1 // Test_2_createThread #include <stdio.h> #include <pthread.h> #include <stdlib.h> #define num_threads. 5 run function threads // void * PrintHelloId (* ThreadID void) { // incoming parameters cast, the pointer becomes non-plastic pointer type, then read int * TID = ((int *) ThreadID); the printf ( "the Hello, World, % D the Thread \ n-", TID); return 0; } int main () { pthread_t pthreads [num_threads]; int i, RC; value i is stored in an array // int Indexes [num_threads]; for (i = 0; I <num_threads; I ++) { the printf ( "main (): D creates a thread% \ n-", I); Indexes [i] = i; // save the value of i // must be converted when indexes passed parameter is untyped pointer RC = pthread_create (& pthreads [I], NULL, PrintHelloId, (void *) & indexes [I]); IF (! 0 = RC) { the printf ( "Error : unable to create a thread \ the n-");! Exit (-1); } } pthread_exit (NULL); return 0; } / * * in CLion (Ubuntu) output is main (): creates a thread 0 main (): create threads 1 the Hello, World, the thread 0 main (): creates a thread 2 the Hello, World, the thread 1 main (): creates a thread 3 the Hello, World, the thread 2 main (): creates a thread 4 the Hello, World, the thread 3 the Hello, world, the Thread 4 * * /
Test 3 the structure passed as a parameter example of concurrent programming thread
// 基于线程的并发编程,向线程传递参数2(传递结构体) // Test_3_createThread #include <stdio.h> #include <pthread.h> #include <stdlib.h> #define NUM_Threads 5 typedef struct thread_data{ int threadid; char message; }THDATA,*PTHDATA; void * PrintHello(void * pthreadid) { PTHDATA tid = (PTHDATA)pthreadid; printf("This is Pthread : %d ;info : %c \n",tid->threadid, tid->message); return 0; } int main(void) { pthread_t Pthread[NUM_Threads]; THDATA index[NUM_Threads]; int i, ret; for (i = 0; i < NUM_Threads; i++) { printf ( "main (): D creates a thread% \ n-", I); index [I] = I .threadid; index [I] .message = 'A' + 10% I; RET = pthread_create (& the Pthread [I] , NULL, printHello, (void *) & index [I]); IF (0 = RET)! { the printf ( "Error:! failed to create thread \ n-"); Exit (-1); } } the pthread_exit (NULL); return 0; } / * * in CLion (Ubuntu) output is main (): creates a thread 0 main (): creates a thread. 1 This iS the Pthread: 0; info: A main (): creates a thread 2 main (): creating a thread. 3 This IS the Pthread: 2; info: C main (): creates a thread. 4 This IS the Pthread:. 3; info: D This IS Pthread: 4; info: E This is Pthread : 1 ;info : B * */
Test Example 4 connecting thread programming
// concurrent programming thread-based, connected or separate thread // Test_4_createThread // 2019 Nian 10 Yue 27 Ri 14:45:11 do not yet fully understand #include <stdio.h> #include <pthread.h> #include <stdlib .h> #define. 5 NUM_Pthread void * printHello (* pthreadid void) { int * TID = ((int *) pthreadid); the printf ( "% Sleeping in Thread D, ... exiting The \ n-", TID); return 0 ; } int main (void) { int I, RET; pthread_t the Pthread [NUM_Pthread]; the pthread_attr_t is attr; // thread attributes defined void * Status; int index [NUM_Pthread]; // initialize and set the thread to be connected pthread_attr_init (& attr) ; pthread_attr_setdetachstate (& attr, PTHREAD_CREATE_JOINABLE); for (i=0; i<NUM_Pthread; i++) { printf("main() : 创建线程 %d \n",i); index[i] = i; ret = pthread_create(&Pthread[i], NULL, PrintHello, (void *)&index[i]); } // 删除属性,并等待其他线程 pthread_attr_destroy(&attr); for (i=0; i<NUM_Pthread; i++) { ret = pthread_join(Pthread[i], status); if (0 != ret) { printf("Error: unable to join,%d\n",ret); exit(-1); } printf("main(): complete thread id : %d",i); printf(" exiting with status : %p\n",status); } printf("main() : program exiting.\n"); pthread_exit(NULL); return 0; }
Semaphore mechanism
Test 5 synchronized writing semaphores
// the amount of synchronization signal #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <semaphore.h> # define Len 100 // set the input content length sem_t bin_sem; char work_area [Len]; // storing the input content void * Thread_func (void * Arg) { // wait semaphore has a value greater than 0 and exit of sem_wait (& bin_sem); the while (! = 0 a strncmp ( "End", work_area,. 3)) { the printf ( "% LD the Input characters \ n-", strlen (work_area) -1); } return 0; } int main (void) { int RES; / / store command return value pthread_t Pthread; // create a thread void * thread_result;// store the result of the processing thread // initializes the semaphore, and set the initial value of 0 RES = sem_init (& bin_sem, 0, 0); IF (0 = RES!) { perror ( "Semaphore Initialization failes"); Exit (EXIT_FAILURE); } // Create a new thread 0 RES = pthread_create (& the Pthread, NULL, Thread_func, NULL); iF (RES = 0)! { perror ( "the Thread Creation failed"); Exit (EXIT_FAILURE); } the printf ( "the Enter 'end' to Finish \ n-"); workspace does not begin // end if string, then continue to enter the while (0 = a strncmp ( "end", work_area,. 3)!) { // Get input to a standard work area fgets (work_area, Len , stdin); sem_post (& bin_sem); // semaphore +1 } the printf ( "\ n-waiting for thread to Finish ... \ n-"); // wait for the end of the thread res = pthread_join (Pthread, &thread_result); if (0 != res) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined\n"); sem_destroy(&bin_sem); // 销毁信号量 exit(EXIT_SUCCESS); return 0; }
Test 6 mutex resources to achieve critical operation
Synchronized with // mutex #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h> #define Len // increment the number of calculations. 3 #define NUM_Pthread 5 // set the thread length int count = 1; // shared resources in the data segment, multiple processes to seize the critical resource // to critical resources, should add mutex pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void * Thread_func (void * threadid) { int TID = * ((int *) ThreadID); int I, Val; the printf ( "the Pthread ID:% D \ n-", TID); for (I = 0; I <NUM_Pthread; I ++) { the pthread_mutex_lock (& the mutex) ; Val = COUNT; the printf ( "Val D =% \ n-", Val ++); COUNT = Val; pthread_mutex_unlock(&mutex); } the printf ("% D COUNT = \ n ", count); return 0; } Int main (void) { int RES; // the return value of the command stored int I; pthread_t the Pthread [NUM_Pthread]; // Create a thread int index [NUM_Pthread]; for (I = 0; I <NUM_Pthread; I ++) { index [i] = i; // create threads RES = pthread_create (& Pthread [i], NULL, Thread_func, (void *) & index [i]); IF (0 = RES!) { printf ( "Error: failed to create thread! \ n-"); Exit (-1); } } for (I = 0; I <NUM_Pthread; I ++) { // merge thread pthread_join (the Pthread [I], NULL); } the pthread_exit (NULL); return 0; } // run this program without mutex, we not only get the wrong answer, and each time the answer is not the same // analysis // when multiple threads in a peer when running concurrently, complete machine instructions in a certain order on a processor, each thread is defined concurrent execution of instructions in a certain order