总结之linux多线程

来源:互联网 发布:java敏捷开发平台 编辑:程序博客网 时间:2024/06/05 05:31


1.Linux的多线程和同步

1)多线程

http://blog.csdn.net/chencheng126/article/details/43916385

Linux是基于进程为单位组织操作,线程也是基于进程。

多线程就是允许在一个进程内存在多个控制权,以便多个函数处于激活状态,从而让多个函数同时运行。即使单CPU的计算机,也可以通过不停地在不同线程的指令切换,从而达到多线程同时运行的效果。

2)并发

多线程相当于一个并发系统。多个任务可以共享资源,特别是同时写入某个变量时,就需要解决同步的问题。

3)多线程的同步

i.互斥锁(mutex)

锁上(lock)和打开(unlock)两个状态。mutex_lock()和mutex_unlock()之间的操作,不会被其它线程影响,形成原子操作。形象的例子:一个人的洗手间。

II.条件变量

条件变量经常与互斥锁合作。它比较适用于多个线程等待某个条件发生的场景。在这种情况下,如果不使用条件变量,每个线程就要不断尝试获得互斥锁,这将大大消耗系统的资源。

举个例子:100个工人装修房子,每人负责装修一个房子。当10个房间装修好以后,老板通知这10个人喝啤酒。

III)读写锁

和互斥锁很类似。它的主要作用是,多线程可以同时读取资源,而具有危险性的写操作则得到了互斥锁的保护。


2.Linux多线程编程详细解析--条件变量

http://blog.csdn.net/chencheng126/article/details/43916355

1)常用的函数

pthread_cond_init,初始化条件变量

pthread_cond_wait,解锁mutex指向的互斥锁,线程阻塞在条件变量上。

pthread_cond_signal,解除在条件变量上的阻塞的某个线程

pthread_cond_timedwait,阻塞直到指定时间,即使条件未发生也会解除。

pthread_cond_broadcast,释放阻塞的所有线程。

pthread_cond_destroy,释放条件变量

2)例子

等待线程
1。使用pthread_cond_wait前要先加锁
2。pthread_cond_wait内部会解锁,然后等待条件变量被其它线程激活
3。pthread_cond_wait被激活后会再自动加锁
激活线程:
1。加锁(和等待线程用同一个锁)
2。pthread_cond_signal发送信号
3。解锁
激活线程的上面三个操作在运行时间上都在等待线程的pthread_cond_wait函数内部。

实用的几个例子,可以参见原文。


3.线程同步之条件变量使用手记

http://blog.csdn.net/chencheng126/article/details/43927607

这篇文章讨论的是,在IO接受到数据的时候,如何高效的通知逻辑线程(基于线程池)工作的问题。类似的例子:餐厅等位问题。领班接到客人后,如何高效的通知侍应生去接待客人。

对于条件变量的理解,为什么有了Mutex,还要再加条件变量。mutex是给资源加的互斥锁,保证对于每个线程,对于资源的操作时个原子操作。而条件变量,是用来阻塞线程。下文中的例子是为了解决假激活的问题,也就是线程被激活了,但是却没有什么活要干。


4.Linux线程开发API以及一些经验

http://blog.csdn.net/chencheng126/article/details/43951311

1.对linux多线程API有一个总结

2.linux多线程中的5条经验

介绍了其它开源类库进行多线程开发,比如boost,对跨平台支持不错,如果要求高稳定的跨平台开发,首选boost.

对象操作Linux Pthread APIWindows SDK 库对应 API线程创建pthread_createCreateThread退出pthread_exitThreadExit等待pthread_joinWaitForSingleObject互斥锁创建pthread_mutex_initCreateMutex销毁pthread_mutex_destroyCloseHandle加锁pthread_mutex_lockWaitForSingleObject解锁pthread_mutex_unlockReleaseMutex条件创建pthread_cond_initCreateEvent销毁pthread_cond_destroyCloseHandle触发pthread_cond_signalSetEvent广播pthread_cond_broadcastSetEvent / ResetEvent等待pthread_cond_wait / pthread_cond_timedwaitSingleObjectAndWait


5.Linux线程池

为什么使用线程池?基本原理?一个简单的例子。

这篇文章说的简单清楚。

http://blog.csdn.net/chencheng126/article/details/43954775


-----------------------------------------------------------------------------------------------------------------------

一个的例子。参见http://blog.csdn.net/chencheng126/article/details/43916355

在linux下通过gcc编译,加上-lpthread

gcc -o pthread_cond2 pthread_cond2.c -lpthread

如果要用gdb调试,编译时需要加上-g参数:

gcc -g -Wall -o pthread_cond2 pthread_cond2.c -lpthread


运行:

./pthread_cond2

#include <stdio.h>#include <pthread.h>#include <unistd.h>pthread_mutex_t counter_lock;pthread_cond_t counter_nonzero;int counter = 0;int estatus = -1;void *decrement_counter(void *argv);void *increment_counter(void *argv);int main(int argc, char **argv){    printf("counter: %d\n", counter);    pthread_t thd1, thd2;    int ret;    ret = pthread_create(&thd1, NULL, decrement_counter, NULL);    if(ret){        perror("del:\n");        return 1;    }    ret = pthread_create(&thd2, NULL, increment_counter, NULL);    if(ret){        perror("inc: \n");        return 1;    }    int counter = 0;    while(counter != 10){        printf("counter(main): %d\n", counter);        sleep(1);        counter++;    }    return 0;}void *decrement_counter(void *argv){    printf("counter(decrement): %d\n", counter);    pthread_mutex_lock(&counter_lock);    while(counter == 0)        pthread_cond_wait(&counter_nonzero, &counter_lock);     printf("counter--(before): %d\n", counter);        counter--;    printf("counter--(after): %d\n", counter);        pthread_mutex_unlock(&counter_lock);     return &estatus;}void *increment_counter(void *argv){    printf("counter(increment): %d\n", counter);    pthread_mutex_lock(&counter_lock);    if(counter == 0)        pthread_cond_signal(&counter_nonzero);    printf("counter++(before): %d\n", counter);        counter++;     printf("counter++(after): %d\n", counter);        pthread_mutex_unlock(&counter_lock);    return &estatus;}

运行结果:

counter: 0
counter(main): 0
counter(decrement): 0
counter(increment): 0
counter++(before): 0
counter++(after): 1
counter--(before): 1
counter--(after): 0
counter(main): 1
counter(main): 2
counter(main): 3
counter(main): 4
counter(main): 5
counter(main): 6
counter(main): 7
counter(main): 8
counter(main): 9





0 0