您的位置:首页 > 其它

PO BO VO DTO POJO DAO概念及其作用(转)

2010-02-01 10:11 399 查看
一.线程分离:

概述:

在任何一一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。一一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(例如栈)是不释放的。相反,一一个分离的线程是不能被其他线程回收或杀死的,它的存储器 资源在它终止止时由系统自自动释放。
默认情况下,线程被创建成可结合的。为了避免存储器泄漏,每个可结合线程都应该要么被显示示地回收,即调用用pthread_join;要么通过调用用pthread_detach函数被分离。
PS:pthread_join函数是以阻塞式等待的,而调用pthread_detach函数则是非阻塞式的等待。
2.相关函数:
pthread_detach函数:pthread_detach(pthread_t thread)
返回值:成功返回0,失败返回一个错误号。

3.相关代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<pthread.h>
4
5 void *create_thread(void *ptr)
6 {
7     pthread_detach(pthread_self());
8     printf("%s",(char *)ptr);
9     return NULL;
10 }
11
12
13 int main()
14 {
15     pthread_t tid;
16     int err = pthread_create(&tid, NULL, create_thread, "thread is running....\n");
17     if(err != 0)
18     {
19         printf("create thread failed,err info is: %s\n", strerror(err));
20     }
21
22     sleep(1);
23     void *errno = NULL;
24     int ret = 0;
25     ret = pthread_join(tid, &errno);
26
27     if(ret != 0)
28     {
29         printf("wait for thread failed, err info is: %d\n",(int)errno);
30     }
31     else
32     {
33         printf("wait for thread success\n");
34     }
35     return ret;
36 }
~
PS:也可以在主线程中分离创建的线程。

执行结果:




二.线程互斥:
概述:

在多线程环境中,可能会发生多个线程同时(相对而言)访问共享数据,就可能会发生冲突。因为修改一个变量不是原子操作,它包括从内存中读取变量,改变寄存器中的值,把寄存器中的值写会内存三步,在其中任何一步都可能有其它线程对这个变量进行操作。所以在多线程中,一个线程要对临界区进行操作,则要使用线程互斥。
解决线程互斥的办法是引入互斥锁(Mutex,MutualExclusive Lock),获得锁的线程可以完成“读-修改-写”的操作,然后释放锁给其它线程,没有获得锁的线程只能等待而而不能访问共享数据,这样“读-修改-写”三步操作组成一一个原子子操作,要么都执行行,要么都不执行行,不会执行行到中间被打断,也不会在其它处理器上并行行做这个操作。
一般情况下,如果同一个线程先后两次调用lock,在第二次调用用时,由于锁已经被占用,该线程会挂起等待别的线程释放锁,然而锁正是被自己占用着的,该线程又被挂起而没有机会释放锁,因此 就永远处于挂起等待状态了,这叫做死锁(Deadlock)。另一种典型的死锁情形是这样:线程A获 得了锁1,线程B获得了锁2,这时线程A调用lock试图获得锁2,结果是需要挂起等待线程B释放 锁2,而这时线程B也调用lock试图获得锁1,结果是需要挂起等待线程A释放锁1,于是线程A和B都 永远处于挂起状态了。不难想象,如果涉及到更多的线程和更多的锁,死锁的问题将会 变得复杂和难以判断。
写程序时应该尽量避免同时获得多个锁,如果一定有必要这么做,则有一个原则:如果所有线程在需要多个锁时都按相同的先后顺序(常见的是按Mutex变量的地址顺序)获得锁,则不会出现死 锁。比如一个程序中用到锁1、锁2、锁3,它们所对应的Mutex变量的地址是锁1<锁2<锁3,那么 所有线程在需要同时获得2个或3个锁时都应该按锁1、锁2、锁3的顺序获得。如果要为所有的锁确 定一个先后顺序比较困难,则应该尽量使用pthread_mutex_trylock调用用代替pthread_mutex_lock 调 用,以免死锁。

2.相关函数:
(1).静态分配(全局变量/static变量):
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER

功能:定义一个全局的或静态的mutex。
(2).pthread_mutex_init函数: int pthread_mutex_init(pthread_mutex_t *restrict mutex,

const pthrad_mutexattr_t *restrict attr)
attr参数:对mutex进行初始化,一般为NULL,表示缺省属性。
返回值:成功返回0,失败返回错误号。
(3).pthread_mutex_destroy函数: int pthread_mutex_destory(pthread_mutex_t *mutex)
函数功能:销毁一个mutex。
返回值:成功返回0,失败返回错误号。
(4).pthread_mutex_lock函数: int pthread_mutex_lock(pthread_mutex_t *mutex)
函数功能:获得一个锁。(阻塞式)
返回值:成功返回0,失败返回错误号。
(5).pthread_mutex_unlock函数:int pthread_mutex_unlock(pthread_mutex_t *mutex)
函数功能:释放一个锁。
返回值:成功返回0,失败返回错误号。
(6).pthread_mutex_trylock函数:int pthread_mutex_trylock(pthread_mutex_t *mutex)
函数功能:获得一个锁。(非阻塞式)
返回值:成功返回0,如果mutex已经被另一个线程获得,则会立即返回EBUSY。

PS:在哪叫互斥锁很关键,在一个适当的位置加锁能提高线程的共享性。因为加互斥锁就相当于一个线程独占了临界资源,但是线程强调共享,所以应当在关键的临界资源处加锁。

3.相关代码:
(1).没有加锁的情况:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<pthread.h>
4
5 const int COUNT = 5000;
6 static int g_count = 0;
7
8 void* create_thread(void *ptr)
9 {
10     pthread_detach(pthread_self());
11     int tem = 0;
12     int i = 0;
13     for(;i < COUNT; i++)
14     {
15         tem = g_count;
16         printf("thread id is:%ul  g_count is:%d\n", (unsigned long)pthread_self(), g_count);
17         g_count = tem + 1;
18     }
19     return NULL;
20 }
21
22
23 int main()
24 {
25     pthread_t tid1;
26     pthread_t tid2;
27     pthread_create(&tid1, NULL, create_thread, NULL);
28     pthread_create(&tid2, NULL, create_thread, NULL);
29     sleep(1);
30
31     printf("end is:%d\n", g_count);
32     return 0;
33 }
执行结果:



图一




图二

如果按正常顺序依次调用线程1和线程2,最终结果应该是10000,但是从图一中可以看出线程进行了切换,两个线程同时访问了临界资源。
(2).加互斥锁的情况:
相关代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<pthread.h>
4
5 const int COUNT = 5000;
6 static int g_count = 0;
7 pthread_mutex_t mutex_lock =  PTHREAD_MUTEX_INITIALIZER;
8
9 void* create_thread(void *ptr)
10 {
11     pthread_detach(pthread_self());
12     int tem = 0;
13     int i = 0;
14     for(;i < COUNT; i++)
15     {
16         pthread_mutex_lock(&mutex_lock);
17         tem = g_count;
18         printf("thread id is:%ul  g_count is:%d\n", (unsigned long)pthread_self(), g_count);
19         g_count = tem + 1;
20         pthread_mutex_unlock(&mutex_lock);
21     }
22     return NULL;
23 }
24
25
26 int main()
27 {
28     pthread_t tid1;
29     pthread_t tid2;
30     pthread_create(&tid1, NULL, create_thread, NULL);
31     pthread_create(&tid2, NULL, create_thread, NULL);
32     sleep(1);
33
34     printf("end is:%d\n", g_count);
35     pthread_mutex_destroy(&mutex_lock);
36     return 0;
37 }
执行结果:



图一



图二



图三
从图一和图二中可以看到,两个线程是没有冲突访问临界资源的。

本文出自 “水仙花” 博客,请务必保留此出处http://10704527.blog.51cto.com/10694527/1765837
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: