Linux under C Development of thread communication

Source: Internet
Author: User
Tags function prototype posix semaphore terminates

Linux under C Development of thread communication (RPM)

1.Linux "Threads"

There is a difference between a process and a thread, but the Linux kernel provides only lightweight process support and does not implement a threading model. Linux is a "multi-process single-threaded" operating system. Linux itself has only the concept of process, and its so-called "thread" is essentially a process in the kernel.

As you know, a process is a unit of resource allocation, and multiple threads in the same process share resources for that process (such as global variables as shared memory). The so-called "thread" in Linux is simply the clone of the parent process's resources when it is created, so it is important to understand that the clone-out process is "thread". Therefore, the concept of the Linux "thread" is only the most accurate in the case of a colon.

At present, the most popular threading mechanism in Linux is Linuxthreads, which is the thread-process "one-to-one" model, which is dispatched to the core, and a thread management mechanism including signal processing is implemented at the user level. Linuxthreads is developed by Xavier Leroy ([email protected]) and has been bundled in glibc, which implements a bicapitalized for Linux-based POSIX 1003.1c "pthread "Standard interface. The Linuxthread can support multiprocessor systems on Intel, Alpha, MIPS and other platforms.

Programs written in the POSIX 1003.1c standard are linked to the Linuxthread library to support multi-threading on the Linux platform and include header file Pthread in the program. h, use the command when compiling the link:

gcc-d-reentrant-lpthread xxx. C


where-reentrant macros make related library functions (such as stdio.h, errno.h functions) reentrant, Thread-safe (thread-safe),- Lpthread means the libpthread.a or libpthread.so file in the link library directory. Using the Linuxthread library requires more than 2.0 versions of the Linux kernel and the corresponding version of the C library (libc 5.2.18, libc 5.4.12, libc 6).

2. "Threading" Control

Thread creation

When a process is created, a main thread is created for it, and to create a new thread in the process, you can call Pthread_create:

Pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *
(Start_routine) (void*), void *arg);


Start_routine is the entry function for the new thread, ARG is the argument passed to Start_routine.

Each thread has its own thread ID to differentiate within the process. The thread ID is returned to the caller of the creation thread when the pthread_create call is made, and a thread can use the pthread_self () call to get its own thread ID after it is created:

Pthread_self (void);


Thread exits

There are three ways to exit a thread:

(1) Implicit exit after completion of execution;

(2) Call the Pthread_exit function to exit by the thread itself display;

Pthread_exit (void * retval);


(3) terminated by another thread with the Pthread_cance function:

Pthread_cance (pthread_t thread);


Call this function in a thread to terminate the thread specified by the parameter thread.

If one thread waits for the termination of another thread, you can use the Pthread_join function, which is that the thread that calls Pthread_join is suspended until a thread with the thread ID of parameter thread terminates:

Pthread_join (pthread_t thread, void** threadreturn);

3. Thread Communication

Thread Mutex

Mutex means "exclusive", that is, two threads cannot enter mutually exclusive protected code at the same time. Linux can be defined by the pthread_mutex_t mutex mechanism to complete the multi-threaded mutex, the role of the mechanism is to a mutually exclusive part, in the first to obtain a mutex, if not get the mutex, that the mutex is owned by other threads, at this time to get the mutex thread blocking, Until the thread that owns the mutex completes the mutex operation.

The following code implements the purpose of protecting shared global variable X with mutex mutex:

int x; Global variables in a process
pthread_mutex_t Mutex;
Pthread_mutex_init (&mutex, NULL); Initialize mutex variable mutex by default property
Pthread_mutex_lock (&mutex); Lock the Mutex variable
...//action on the variable x
Phtread_mutex_unlock (&mutex); Unlocking a Mutex variable


Thread synchronization

Synchronization is the thread waiting for an event to occur. The thread hangs and discards the processor only if the waiting event occurs line friend continues execution. When multiple threads work together, the interacting tasks must be synchronized under certain conditions.

C programming under Linux has a variety of thread synchronization mechanisms, most typically conditional variables (condition variable). Pthread_cond_init is used to create a conditional variable whose function prototype is:

Pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr);


Pthread_cond_wait and pthread_cond_timedwait are used to wait for the condition variable to be set, it is worth noting that these two wait calls need a locked mutex mutex, This is to prevent the competition from the possibility that other threads might set the condition variable before actually entering the wait state. The function prototypes for pthread_cond_wait are:

Pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);


Pthread_cond_broadcast is used to set the condition variable, even if an event occurs, so that the thread waiting for the event will no longer block:

Pthread_cond_broadcast (pthread_cond_t *cond);


The pthread_cond_signal is used to unblock a waiting thread from the blocking state:

Pthread_cond_signal (pthread_cond_t *cond);


Pthread_cond_destroy is used to release a resource for a condition variable.

The semaphore defined in the header file Semaphore.h completes the encapsulation of the mutex and the conditional variable, and according to the access control mechanism in the multi-thread program design, it controls the synchronization access to the resource, and provides the programming designer with more convenient calling interface.

Sem_init (sem_t *sem, int pshared, unsigned int val);


This function initializes a semaphore with a value of Val, and the parameter pshared is a shared property control that indicates whether it is shared between processes.

Sem_wait (sem_t *sem);


When the function is called, if the SEM is stateless, the calling thread blocks, waiting for the semaphore to increase (post) to become signaled; if the SEM is stateful, the calling thread executes sequentially, but the value of the semaphore is reduced by one.

Sem_post (sem_t *sem);


Call this function, the value of the semaphore SEM increases, can be changed from no signal state to a signal state.

4. Example

The following is an example of a producer/consumer problem that describes the control and communication of Linux threads. A set of producer threads is associated with a set of consumer threads through a buffer. The producer thread feeds the produced product into a buffer and the consumer thread extracts the product from it. The buffer has n and is a ring buffer pool.

#include <stdio.h>
#include <pthread.h>
#define BUFFER_SIZE 16//Number of buffers
struct prodcons
{
Buffer-related data structures
int buffer[buffer_size]; /* Array of actual data stored */
pthread_mutex_t lock; /* Mutex lock for mutex operation against buffer */
int Readpos, Writepos; /* Read/write pointer */
pthread_cond_t Notempty; /* Buffer non-empty condition variable */
pthread_cond_t Notfull; /* Buffer not full condition variable */
};
/* Initialize the buffer structure */
void init (struct prodcons *b)
{
Pthread_mutex_init (&b->lock, NULL);
Pthread_cond_init (&b->notempty, NULL);
Pthread_cond_init (&b->notfull, NULL);
B->readpos = 0;
B->writepos = 0;
}
/* Put the product into a buffer, here is an integer */
void put (struct prodcons *b, int data)
{
Pthread_mutex_lock (&b->lock);
/* Wait buffer is not full */
if ((B->writepos + 1)% Buffer_size = = B->readpos)
{
Pthread_cond_wait (&b->notfull, &b->lock);
}
/* Write the data and move the pointer */
B->buffer[b->writepos] = data;
b->writepos++;
if (B->writepos > = buffer_size)
B->writepos = 0;
/* Set the buffer non-NULL condition variable */
Pthread_cond_signal (&b->notempty);
Pthread_mutex_unlock (&b->lock);
}
/* Remove the integer from the buffer */
int get (struct prodcons *b)
{
int data;
Pthread_mutex_lock (&b->lock);
/* Wait buffer not empty */
if (B->writepos = = B->readpos)
{
Pthread_cond_wait (&b->notempty, &b->lock);
}
/* Read the data, move the read pointer */
data = b->buffer[b->readpos];
b->readpos++;
if (B->readpos > = buffer_size)
B->readpos = 0;
/* Set the condition variable for which the buffer is not full */
Pthread_cond_signal (&b->notfull);
Pthread_mutex_unlock (&b->lock);
return data;
}

/* Test: The producer thread feeds a 1 to 10000 integer into the buffer, and the consumer line
The process obtains an integer from the buffer, both print information */
#define OVER (-1)
struct Prodcons buffer;
void *producer (void *data)
{
int n;
for (n = 0; n < 10000; n++)
{
printf ("%d--->\n", n);
Put (&buffer, n);
} put (&buffer, over);
return NULL;
}

void *consumer (void *data)
{
int D;
while (1)
{
D = Get (&buffer);
if (d = = over)
Break
printf ("--->%d \ n", d);
}
return NULL;
}

int main (void)
{
pthread_t th_a, Th_b;
void *retval;
Init (&buffer);
/* Create producer and Consumer threads */
Pthread_create (&th_a, NULL, producer, 0);
Pthread_create (&th_b, NULL, consumer, 0);
/* Wait for two threads to end */
Pthread_join (Th_a, &retval);
Pthread_join (Th_b, &retval);
return 0;
}

5.win32, VxWorks, Linux threading analogy

So far, the author has created the "multi-task concurrent programming based on embedded operating system VxWorks" ("Software Report" 2006 5~12 period serial), "Win32 multithreaded Programming" (Yesky Technical topics) series, we come to find the two series of articles and this article in common points.

Look at the technical problem to aim at its essence, whether it is Linux, VxWorks or WIN32, its related to multi-threaded parts are those content, nothing but thread control and thread communication, many of their functions are only different names, the essence of the meaning is equivalent, Let's make a list of the three major operating systems in common. Detail form:

Matters WIN32 VxWorks Linux
Thread creation CreateThread Taskspawn Pthread_create
Thread termination Exits when execution is complete, terminates itself when the thread calls the ExitThread function itself; Call the function TerminateThread function by another thread Exit after execution completes; call exit from thread itself; Call function Taskdelete terminated by other thread Exit after execution completes; call Pthread_exit exit by thread itself; Call function pthread_cance terminate by other thread
Get thread ID GetCurrentThreadID Taskidself Pthread_self
Create Mutex CreateMutex Semmcreate Pthread_mutex_init
Get Mutex WaitForSingleObject, WaitForMultipleObjects Semtake Pthread_mutex_lock
Release Mutex ReleaseMutex Semgive Phtread_mutex_unlock
Create semaphore CreateSemaphore Sembcreate, Semccreate Sem_init
Wait for the semaphore WaitForSingleObject Semtake Sem_wait
Release semaphore ReleaseSemaphore Semgive Sem_post

   6. Summary

This chapter describes the control of multithreading under Linux and the method of inter-threading communication programming, gives a producer/consumer example, and the multi-threading of Linux and WIN32, VxWorks Multi-threading, summed up the general law. Since multithreaded programming has become the mainstream way to develop concurrent applications, it is self-evident to learn the meaning of this chapter.

Linux under C Development of thread communication (RPM)

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.