1. Linux "threads"
There is a difference between processes and threads, but linux kernel only provides support for lightweight processes, unrealized threading model. Linux is a "multi-process single-threaded," the operating system . Linux itself is only the process of concept, and its so-called "thread" in the kernel is still nature of the process.
As we all know, is the process of resource allocation units, multiple threads in the same process share the resources of the process (such as a global variable shared memory). Linux in the so-called "thread" is just clone was created when the resources of the parent process, so the clone out of the process performance of the "thread", which is sure to clarify. Therefore, Linux "thread" concept only in the case of playing the colon is the most accurate.
Linux is currently the most popular thread mechanism LinuxThreads, is used by a thread - the process of "one on one" model, scheduling to the core, and in the user-level thread management mechanism to achieve, including signal processing, including. LinuxThreads by the Xavier Leroy ([email protected]) responsible for the development completed and binding in GLIBC issue, which implements a BiCapitalized for Linux, Posix 1003.1c "pthread" standard interface. Linuxthread can support multi-processor systems on the platform Intel, Alpha, MIPS and so on.
POSIX 1003.1c prepared in accordance with standard procedures and Linuxthread library linked to support multi-threading on the Linux platform, the program needs to include the header file pthread h, use the command when compiling links:
gcc -D -REENTRANT -lpthread xxx. c |
-REENTRANT which makes macro-related library functions (such as stdio.h, errno.h in function) is reentrant and thread-safe (thread-safe), - lpthread means libpthread.a or libpthread next link library catalog .so file. Use Linuxthread library requires version 2.0 or later of the Linux kernel and the appropriate version of the C library (libc 5.2.18, libc 5.4.12, libc 6).
2. "thread" control
thread is created
when the process is created, the system will create a main thread, but 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 for the new thread entry function, arg parameter is passed to the start_routine.
Each thread has its own thread ID, in order to distinguish in the process. Return thread ID to create the caller's thread in the pthread_create call; one thread can also be used pthread_self after creating () call to get its own thread ID:
pthread_self (void) ; |
Thread exits
thread exit strategy are threefold:
(1) Upon completion of the implementation of implicit exit;
(2) by the thread itself shows the call pthread_exit function exits;
pthread_exit (void * retval) ; |
(3) by another thread function terminates with pthread_cance:
pthread_cance (pthread_t thread) ; |
This function is called in a thread can be terminated by the specified parameters thread thread.
If one thread to wait for another thread to terminate, you can use pthread_join function, that function does is to call pthread_join thread will be suspended until the thread ID for the thread to terminate the thread parameters:
pthread_join (pthread_t thread, void** threadreturn); |
3. Thread the communication
thread mutex
mutex means "exclusive", that is, two threads can not enter the exclusive protection code. Linux can be done by pthread_mutex_t defined mutex mutex operation of multi-threaded mechanism, the role of the mechanism is a need for mutually exclusive part, upon entering first get mutex, mutex if not, show mutual repellent portion is owned by other threads, thread blocking to obtain this case mutex until the thread owns the mutex operations is completed mutually exclusive portion.
The following code to achieve the object of the shared global variable x to be protected by a mutex mutex is:
int x; // global variables in the process of pthread_mutex_t mutex; pthread_mutex_init (& mutex, NULL); // initialize attributes by default mutex variable mutex pthread_mutex_lock (& mutex); // variable to the mutex lock ... // operation of the variable x phtread_mutex_unlock (& mutex); // unlock a mutex variable |
Thread Synchronization
Synchronization thread is waiting for an event to occur. Only when waits event before continuing execution thread, or the thread hangs and give up the processor. When multiple threads collaboration, interaction tasks must be synchronized under certain conditions.
Under Linux C language programming has a variety of thread synchronization mechanisms, the most typical is the condition variable (condition variable). pthread_cond_init used to create a condition variable, its function prototype is:
pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr); |
pthread_cond_wait and pthread_cond_timedwait to wait for condition variable is set, it is worth noting that these two need to wait for a call already locked mutex mutex, which is to prevent the state before actually entering the waiting another thread is possible to set the condition variable and compete. Pthread_cond_wait function prototype is:
pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex); |
pthread_cond_broadcast for setting a condition variable, even if the incident was, so the waiting thread that the event will no longer be blocked:
pthread_cond_broadcast (pthread_cond_t *cond) ; |
pthread_cond_signal is used to unblock a certain waiting threads:
pthread_cond_signal (pthread_cond_t *cond) ; |
pthread_cond_destroy the release of resources for a condition variable.
The amount of signal is defined in the header file in the completed package semaphore.h mutex and condition variables, and access control mechanisms designed in a multithreaded program, the synchronization control access to resources, personnel provide easier programming call interface.
sem_init(sem_t *sem, int pshared, unsigned int val); |
This function initializes the value of a semaphore sem val, pshared parameter control is shared property, it indicates whether shared between processes.
sem_wait (not sem_t *); |
The function is called, if the sem-free state, the calling thread blocked waiting for the semaphore value increases sem (POST) becomes the signal state; sem if there is a state, the calling thread sequentially performed, but the value of the semaphore by one.
sem_post (not sem_t *); |
Calling the function, the value of the semaphore sem increases from no signal state to be signaled.
4. Examples
Here we are still in the name of the producer / consumer issue as an example to illustrate the control and communication Linux thread. Contact a group of a group of consumers and the producer thread by thread occurred buffer. The producer thread production of goods into the buffer, the consumer thread is removed from the product. There are N buffers, an annular pool.
[cpp] view plain copy
- #include <stdio.h>
- #include <pthread.h>
- 16 // number of buffers #define BUFFER_SIZE
- struct prodcons
- {
- // buffer data structure
- int buffer [BUFFER_SIZE]; / * store the actual data array * /
- pthread_mutex_t lock; / * mutex lock for mutual exclusion to the buffer * /
- int readpos, writepos; / * read pointer * /
- pthread_cond_t notempty; / * buffer is not empty condition variable * /
- pthread_cond_t notfull; / * buffer is not full in the 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;
- }
- / * Product into the buffer zone, there is deposited an integer * /
- void put(struct prodcons *b, int data)
- {
- pthread_mutex_lock(&b->lock);
- / * Wait for the buffer is not full * /
- if ((b->writepos + 1) % BUFFER_SIZE == b->readpos)
- {
- pthread_cond_wait(&b->notfull, &b->lock);
- }
- / * Write data, and move the pointer * /
- b->buffer[b->writepos] = data;
- b->writepos++;
- if (b->writepos >= BUFFER_SIZE)
- b->writepos = 0;
- / * Set the buffer is not empty condition variable * /
- pthread_cond_signal(&b->notempty);
- pthread_mutex_unlock(&b->lock);
- }
- / * Integer removed from the buffer * /
- int get(struct prodcons *b)
- {
- int data;
- pthread_mutex_lock(&b->lock);
- / * Wait for the buffer is not empty * /
- if (b->writepos == b->readpos)
- {
- pthread_cond_wait(&b->notempty, &b->lock);
- }
- / * Read data, the read pointer moves * /
- data = b->buffer[b->readpos];
- b->readpos++;
- if (b->readpos >= BUFFER_SIZE)
- b->readpos = 0;
- / * Set the condition variable buffer is not full of * /
- pthread_cond_signal(&b->notfull);
- pthread_mutex_unlock(&b->lock);
- return data;
- }
- / * Test: producer thread integer from 1 to 10,000 into the buffer, the consumer line
- Cheng obtain 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 the producer and consumer threads * /
- pthread_create(&th_a, NULL, producer, 0);
- pthread_create(&th_b, NULL, consumer, 0);
- / * Wait for the end of the two threads * /
- pthread_join(th_a, &retval);
- pthread_join(th_b, &retval);
- return 0;
- }
5.WIN32, VxWorks, Linux thread analogy
so far, the author has created a "multi-task concurrent programming based on VxWorks embedded operating system design" ( "Software News" in 2006 from 5 to 12 serial), "in layman's language Win32 multi-threaded programs design "(NEW YORK technical topics) series, we have to find a common point of these two series of articles to this article.
Look at technical issues to aim its nature, whether it is Linux, VxWorks or WIN32, it relates to the content of those parts are multithreaded, nothing more than a thread and thread control communications, many of their functions but different names, its real meaning is equivalent , here we come three columns a common operating system in detail form:
matter | WIN32 | VxWorks | Linux |
Thread Creation | CreateThread | taskSpawn | pthread_create |
Thread Termination | After the completion of the implementation of exit; thread function terminates their call ExitThread himself; by another thread function calls the function TerminateThread | After the completion of the implementation of exit; exit to exit the call by the thread itself; termination of another thread calls the function taskDelete | After the completion of the implementation of exit; pthread_exit call itself by a thread exit; termination of another thread calls the function pthread_cance |
Get Thread ID | GetCurrentThreadId | taskIdSelf | pthread_self |
Creating mutually exclusive | CreateMutex | semMCreate | pthread_mutex_init |
Acquire the mutex | WaitForSingleObject、WaitForMultipleObjects | semTake | pthread_mutex_lock |
Release the mutex | ReleaseMutex | semGive | phtread_mutex_unlock |
Create Semaphore | CreateSemaphore | semBCreate、semCCreate | sem_init |
Waiting for the semaphore | WaitForSingleObject | semTake | sem_wait |
Release Semaphore | ReleaseSemaphore | semGive | sem_post |
6. Summary
This chapter describes the Linux multithreading control and inter-thread communication program, shows an example of a producer / consumer, and Linux multithreading and WIN32, VxWorks multi-thread analogy, a general summary law. Given the multi-threaded programming has become the mainstream method development of concurrent applications, meaning they will learn in this chapter is self-evident.
Finish
[cpp] view plain copy
- #include <stdio.h>
- #include <stdio.h>
- #include <pthread.h>
- void thread(void)
- {
- int i;
- for(i=0;i<3;i++)
- printf("This is a pthread.\n");
- }
- int main(void)
- {
- pthread_t id;
- int i,ret;
- ret=pthread_create(&id,NULL,(void *) thread,NULL);
- if(ret!=0){
- printf ("Create pthread error!\n");
- exit (1);
- }
- for(i=0;i<3;i++)
- printf("This is the main process.\n");
- pthread_join(id,NULL);
- return (0);
- }
编译:
gcc example1.c -lpthread -o example1
[cpp] view plain copy
- #include <pthread.h>
- #include <stdio.h>
- #include <sys/time.h>
- #include <string.h>
- #define MAX 10
- pthread_t thread[2];
- pthread_mutex_t mut;
- int number=0, i;
- void *thread1()
- {
- printf ("thread1 : I'm thread 1\n");
- for (i = 0; i < MAX; i++)
- {
- printf("thread1 : number = %d\n",number);
- pthread_mutex_lock(&mut);
- number++;
- pthread_mutex_unlock(&mut);
- sleep(2);
- }
- printf("thread1 :主函数在等我完成任务吗?\n");
- pthread_exit(NULL);
- }
- void *thread2()
- {
- printf("thread2 : I'm thread 2\n");
- for (i = 0; i < MAX; i++)
- {
- printf("thread2 : number = %d\n",number);
- pthread_mutex_lock(&mut);
- number++;
- pthread_mutex_unlock(&mut);
- sleep(3);
- }
- printf("thread2 :主函数在等我完成任务吗?\n");
- pthread_exit(NULL);
- }
- void thread_create(void)
- {
- int temp;
- memset(&thread, 0, sizeof(thread)); //comment1
- //创建线程
- if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0) //comment2
- printf("线程1创建失败!\n");
- else
- printf("线程1被创建\n");
- if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0) //comment3
- printf("线程2创建失败");
- else
- printf("线程2被创建\n");
- }
- void thread_wait(void)
- {
- //等待线程结束
- if(thread[0] !=0) { //comment4
- pthread_join(thread[0],NULL);
- printf("线程1已经结束\n");
- }
- if(thread[1] !=0) { //comment5
- pthread_join(thread[1],NULL);
- printf("线程2已经结束\n");
- }
- }
- int main()
- {
- //用默认属性初始化互斥锁
- pthread_mutex_init(&mut,NULL);
- printf("我是主函数哦,我正在创建线程,呵呵\n");
- thread_create();
- printf("我是主函数哦,我正在等待线程完成任务阿,呵呵\n");
- thread_wait();
- return 0;
- }