POSIX multi-thread-asynchronous programming example

Source: Internet
Author: User
Tags sleep function

Author: APO
Link: http://blog.csdn.net/livelylittlefish/article/details/7952884

(I haven't updated it all over the past six months. I have sent several previous Reading Notes .)

Content

0. Order

1. Basic synchronization version

2. multi-process version

3. multi-threaded version

4. Summary

 

 

0. Order

 

This section uses a simple alarm clock instance to demonstrate asynchronous programming.

This program cyclically accepts user input information until an error or input is complete. Each line of information entered by the user has two parts: the waiting time (seconds) of the alarm and the text information displayed when the alarm time arrives.

 

1. Basic synchronization version

The Code is as follows.

/* * alarm.c * * Simple synchronous alarm program. This is used as a * reference for progressive examples of asynchronous * alarm programs. */#include "errors.h"int main (int argc, char **argv){    int seconds;    char line[128];    char message[64];    while (1)    {        printf("Alarm> ");        if (fgets(line, sizeof(line), stdin) == NULL)            exit(0);        if (strlen(line) <= 1)            continue;        /**         Parse input line into seconds (%d) and a message (%64[^\n]),          consisting of up to 64 characters separated from the seconds         by whitespace.        */        if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2)        {            fprintf(stderr, "Bad command\n");        }        else        {            sleep(seconds);            printf("(%d) %s\n", seconds, message);        }    }}

Features: asynchronous synchronization is implemented. After an alarm request is sent, the program waits for the alarm time to arrive;

Problem: the synchronous method is used to implement Asynchronization, so only one alarm request can be processed at a time; that is, the next alarm request can be performed only after the program's sleep time;

Running result.

#. /Alarmalarm> 5bad commandalarm> 5 this is a test with 5 seconds (5) this is a test with 5 seconds // wait 5 seconds and print the message. Alarm> 10 the seconds with 10 seconds (10) the seconds with 10 seconds // wait 10 seconds and print the message. Alarm>

2. multi-process version

The Code is as follows.

/* * alarm_fork.c * * This version of alarm.c uses fork to create a new process to * wait for each alarm to expire. */#include <sys/types.h>#include <wait.h>#include "errors.h"int main(int argc, char **argv){    int status;    char line[128];    int seconds;    pid_t pid;    char message[64];    while (1)    {        printf ("Alarm> ");        if (fgets(line, sizeof(line), stdin) == NULL) exit(0);        if (strlen(line) <= 1) continue;        /**         Parse input line into seconds (%d) and a message (%64[^\n]),          consisting of up to 64 characters separated from the seconds         by whitespace.        */        if (sscanf(line, "%d %64[^\n]", &seconds, message) < 2)        {            fprintf(stderr, "Bad command\n");        }        else        {            pid = fork();            if (pid == (pid_t)-1)                errno_abort("Fork");            if (pid == (pid_t)0)            {                /*                 * If we're in the child, wait and then print a message                 */                sleep(seconds);                printf("pid = %d, (%d) %s\n", pid, seconds, message);                exit(0);            }            else            {                /*                 * In the parent, call waitpid() to collect any children that                 * have already terminated.                 */                do                {                    printf("line = %d, pid = %d\n", __LINE__, pid);                    pid = waitpid((pid_t)-1, NULL, WNOHANG);                    printf("line = %d, pid = %d\n", __LINE__, pid);                    if (pid == (pid_t)-1)                        errno_abort("Wait for child");                } while (pid != (pid_t)0);            }         }    }}

Features: The sleep function is called asynchronously in the child process, while the parent process continues to run;

Problem: fork is used to create sub-processes for each alarm request, causing excessive program overhead;

Waitpid () function

  • Wnohang: the parent process does not have to be suspended until the child process ends;
  • If a child process is terminated, the function recycles the resources of the child process;
  • If no sub-process is terminated, the function immediately returns pid = 0; the parent process continues to recycle the terminated sub-process until no sub-process is terminated;
  • Call waitpid cyclically after each command to recycle all the child processes that have ended;

Running result.

Alarm> 3 Test 1 // enter the command alarm> 5 Test 2 // enter the command alarm> (3) test 1 // wait 3 seconds and print the Message 10 Test 3 // enter the command alarm> (5) Test 2 // wait 5 seconds and print the message alarm> (10) test 3 // wait 10 seconds and print the message alarm> #. /alarm_forkalarm> 5 Test 1 line = 56, pid = 7901 line = 58, pid = 0 alarm> 10 Test 2 line = 56, pid = 7902 line = 58, PID = 0 alarm> pid = 0, (5) test 1pid = 0, (10) Test 2 alarm> 15 test 3 line = 56, pid = 7904 line = 58, PID = 7901 line = 56, pid = 7901 line = 58, pid = 7902 line = 56, pid = 7902 line = 58, pid = 0 alarm> pid = 0, (15) test 3 alarm>

3. multi-threaded version

The Code is as follows.

/* * alarm_fork.c * * This version of alarm.c uses pthread_create to create a * separate thread to wait for each alarm to expire. */#include <pthread.h>#include "errors.h"typedef struct alarm_tag {    int         seconds;    char       message[64];} alarm_t;void *alarm_thread (void *arg){    alarm_t *alarm = (alarm_t*)arg;    int status;    status = pthread_detach (pthread_self ());    if (status != 0)        err_abort (status, "Detach thread");    sleep (alarm->seconds);    printf ("(%d) %s\n", alarm->seconds, alarm->message);    free (alarm);    return NULL;}int main (int argc, char *argv[]){    int status;    char line[128];    alarm_t *alarm;    pthread_t thread;    while (1) {        printf ("Alarm> ");        if (fgets (line, sizeof (line), stdin) == NULL) exit (0);        if (strlen (line) <= 1) continue;        alarm = (alarm_t*)malloc (sizeof (alarm_t));        if (alarm == NULL)            errno_abort ("Allocate alarm");        /*         * Parse input line into seconds (%d) and a message         * (%64[^\n]), consisting of up to 64 characters         * separated from the seconds by whitespace.         */        if (sscanf (line, "%d %64[^\n]", &alarm->seconds, alarm->message) < 2) {            fprintf (stderr, "Bad command\n");            free (alarm);        } else {            status = pthread_create(&thread, NULL, alarm_thread, alarm);            if (status != 0)                err_abort (status, "Create alarm thread");        }    }}

Features: In this example, the alarm thread calls the pthread_detach () function to separate itself, notifying pthreads that it does not have to care about its termination time and exit status; therefore, it does not need to wait for the thread to end, unless you want to obtain its return value. Resources of the alarm thread are immediately recycled after it is terminated.

Generally, pthreads stores the thread resources so that other threads know that it has been terminated and obtain its final result. In this example, the alarm thread is responsible for separating itself.

This version uses the following functions:

  • Pthread_create (): Creates a thread. The Running code is specified by the third parameter. parameters required for running the code are passed in by the fourth parameter. The return thread identifier;
  • Pthread_detach (): When the thread is terminated, pthreads is allowed to immediately recycle the thread resources;
  • Pthread_exit (): Terminate the call thread;

Running result.

# ./alarm_threadAlarm> 5 atestAlarm> 10 btestAlarm> (5) atestAlarm> 15 ctestAlarm> (10) btest(15) ctestAlarm> 

4. Summary

Multi-process version

  • Each alarm clock has an independent address space copied from the master process;
  • The main process calls waitpid to tell the system to release its created sub-process resources;

Multi-threaded version

  • All threads share the same address space;
  • You do not need to wait until the thread ends, unless you want to get its return value;
  • Faster message transmission between threads
    • No need to map shared memory;
    • You do not need to read or write data through pipelines;
    • There is no need to worry about consistency of the address pointers transmitted between processes;
  • Threads share everything: valid address pointers in a thread are equally valid in all threads;

Advantages of Multithreading

  • Develop Program parallelism in a multi-processor system (only concurrency requires special hardware support );
  • When the slow peripheral I/O operation ends, the program can execute other computations to provide more effective and natural development methods for program concurrency;
  • A modular programming model that clearly expresses the relationships between independent events in a program;

Disadvantages of Multithreading

  • Computing load, such as the time required for synchronization between threads;
  • Good programming rules should be set up, such as avoiding deadlocks, competition, and priority inversion;
  • More difficult to debug;

Which applications are suitable for multithreading?

  • Computing-intensive applications are implemented in multiple threads to run on a multi-processor system;
  • Io-intensive applications overlap Io operations to improve performance, such as distributed servers;

 

Reference

# Man waitpid

# Man pthread_create

# Man pthread_detach

 

 

Related Article

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.