Multithreading C language mutex semaphore exemplary language understanding thread synchronization C

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

Reference Hirofumi:

Guess you like

Origin www.cnblogs.com/Robin5/p/11748016.html