linux线程互斥与同步---互斥锁
2014-02-24 11:48
183 查看
由于线程是共享进程的资源和空间的,所以对这些资源进行操作时,必须考虑到线程间资源访问的同步与互斥问题,这里主要说的是POSIX中的两种线程同步机制,分别为互斥锁和信号量,这两种同步机制能够互相调用对方来实现,但互斥锁使用与同时可用的资源是唯一的情况,信号量更适用于同时可用的资源为多个的情况。
互斥锁:是一种简单的加锁方法来控制对共享资源的原子操作,这个互斥锁只有两种状态:上锁,解锁,可以把互斥锁看成某种意义上的全局变量,在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作,若其他线程希望上锁一个已经被上锁的互斥锁,则被挂起,直到上锁的线程释放掉互斥锁为止,所以互斥锁保证了每个线程对共享资源按顺序进行原子操作。
互斥锁主要包括下面的基本函数:
互斥锁初始化:pthread_mutex_init()
互斥锁上锁:pthread_mutex_lock()
互斥锁判断上锁:pthread_mutex_trylock()
互斥锁解锁:pthread_mutex_unlock()
消除互斥锁:pthread_mutex_destroy()
互斥锁分为快速互斥锁,递归互斥锁,检错互斥锁。这三种锁得区别主要是在未占有互斥锁的线程在希望得到互斥锁时是否需要阻塞等待,默认的是快速互斥锁
快速锁:调用线程会阻塞直到拥有互斥锁得线程解锁为止
递归互斥锁:能够成功的返回,并且增加调用线程在互斥锁上加锁的次数
检错互斥锁:快速互斥锁的非阻塞版本,他会立即返回一个错误信息
pthread_mutex_init()函数格式如下:
pthread_mutex_lock()等函数的语法如下:
下面的这个实例是在前面的基础上增加了锁功能,实现原本独立与无序的线程按顺序执行:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREAD_NUMBER 3//线程个数
#define REPEAT_NUMBER 3
#define DELAY_TIME_LEVELS 10.0
void *thrd_func(void *arg)//线程函数
{
int thrd_num = (int)arg ;
int delay_time = 0 ;
int count = 0 ;
int res ;
res = pthread_mutex_lock(&mutex) ;//上锁
if (res)
{
printf("thread %d lock failed\n", thrd_num) ;
pthread_exit(NULL) ;
}
printf("thread %d is starting\n", thrd_num) ;
for (count = 0; count < REPEAT_NUMBER; count++)//每个线程完成五次任务
{
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;//产生随机时间
sleep(delay_time) ;
printf("\tThread %d:job %d delay = %d\n",
thrd_num, count, delay_time) ;
}
printf("thread %d finished\n", thrd_num) ;
pthread_exit(NULL) ;
}
int main()
{
pthread_t thread[THREAD_NUMBER] ;
int no = 0, res ;
void *thrd_ret ;
srand(time(NULL)) ;//产生随机种子
pthread_mutex_init(&mutex, NULL ) ;//初始化互斥锁,默认的是快速互斥锁
for(no = 0; no < THREAD_NUMBER; no++)
{
res = pthread_create(&thread[no], NULL, thrd_func, (void *)no) ;//创建线程
if (res != 0)
{
printf("create thread %d failed\n", no) ;
exit(res) ;
}
}
printf("create threads success\n waiting for threads to finish...\n") ;
for (no = 0; no < THREAD_NUMBER; no++)
{
res = pthread_join(thread[no], &thrd_ret) ;//等待线程结束
if (!res)
{
printf("thread %d joined\n", no) ;
}
else
{
printf("thread %d joined failed", no) ;
}
pthread_mutex_unlock(&mutex) ;//解锁
}
pthread_mutex_destroy(&mutex) ;//消除锁
exit(0) ;
}
程序执行如下:
可以看出这个按照线程创建时的顺序执行的,第一个进程执行时上锁必须等到线程退出时才能解锁,下一个线程才能执行。
互斥锁:是一种简单的加锁方法来控制对共享资源的原子操作,这个互斥锁只有两种状态:上锁,解锁,可以把互斥锁看成某种意义上的全局变量,在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作,若其他线程希望上锁一个已经被上锁的互斥锁,则被挂起,直到上锁的线程释放掉互斥锁为止,所以互斥锁保证了每个线程对共享资源按顺序进行原子操作。
互斥锁主要包括下面的基本函数:
互斥锁初始化:pthread_mutex_init()
互斥锁上锁:pthread_mutex_lock()
互斥锁判断上锁:pthread_mutex_trylock()
互斥锁解锁:pthread_mutex_unlock()
消除互斥锁:pthread_mutex_destroy()
互斥锁分为快速互斥锁,递归互斥锁,检错互斥锁。这三种锁得区别主要是在未占有互斥锁的线程在希望得到互斥锁时是否需要阻塞等待,默认的是快速互斥锁
快速锁:调用线程会阻塞直到拥有互斥锁得线程解锁为止
递归互斥锁:能够成功的返回,并且增加调用线程在互斥锁上加锁的次数
检错互斥锁:快速互斥锁的非阻塞版本,他会立即返回一个错误信息
pthread_mutex_init()函数格式如下:
pthread_mutex_lock()等函数的语法如下:
下面的这个实例是在前面的基础上增加了锁功能,实现原本独立与无序的线程按顺序执行:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREAD_NUMBER 3//线程个数
#define REPEAT_NUMBER 3
#define DELAY_TIME_LEVELS 10.0
void *thrd_func(void *arg)//线程函数
{
int thrd_num = (int)arg ;
int delay_time = 0 ;
int count = 0 ;
int res ;
res = pthread_mutex_lock(&mutex) ;//上锁
if (res)
{
printf("thread %d lock failed\n", thrd_num) ;
pthread_exit(NULL) ;
}
printf("thread %d is starting\n", thrd_num) ;
for (count = 0; count < REPEAT_NUMBER; count++)//每个线程完成五次任务
{
delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;//产生随机时间
sleep(delay_time) ;
printf("\tThread %d:job %d delay = %d\n",
thrd_num, count, delay_time) ;
}
printf("thread %d finished\n", thrd_num) ;
pthread_exit(NULL) ;
}
int main()
{
pthread_t thread[THREAD_NUMBER] ;
int no = 0, res ;
void *thrd_ret ;
srand(time(NULL)) ;//产生随机种子
pthread_mutex_init(&mutex, NULL ) ;//初始化互斥锁,默认的是快速互斥锁
for(no = 0; no < THREAD_NUMBER; no++)
{
res = pthread_create(&thread[no], NULL, thrd_func, (void *)no) ;//创建线程
if (res != 0)
{
printf("create thread %d failed\n", no) ;
exit(res) ;
}
}
printf("create threads success\n waiting for threads to finish...\n") ;
for (no = 0; no < THREAD_NUMBER; no++)
{
res = pthread_join(thread[no], &thrd_ret) ;//等待线程结束
if (!res)
{
printf("thread %d joined\n", no) ;
}
else
{
printf("thread %d joined failed", no) ;
}
pthread_mutex_unlock(&mutex) ;//解锁
}
pthread_mutex_destroy(&mutex) ;//消除锁
exit(0) ;
}
程序执行如下:
可以看出这个按照线程创建时的顺序执行的,第一个进程执行时上锁必须等到线程退出时才能解锁,下一个线程才能执行。
相关文章推荐
- linux线程互斥与同步---互斥锁
- 同步与互斥
- 操作系统清华向勇陈渝版笔记(九) 同步协同多道程序设计和并发问题,同步互斥,死锁,临界区
- 进程间互斥与同步
- 一起talk C栗子吧(第一百零二回:C语言实例--使用信号量进行进程间同步与互斥三)
- 同步和互斥
- linux 多线程编程 同步与互斥
- 线程的同步与互斥:互斥锁
- 线程的同步与互斥:条件变量&信号量
- 操作系统精髓与设计原理--并发性:互斥和同步
- Linux下面线程的操作、多线程的同步和互斥
- 文件传输项目模块2互斥与同步
- 同步与互斥概念
- Linux下生产者消费者问题详细分析(操作系统期中考试论文---并发程序的同步和互斥)
- Windows多线程学习(三)多线程互斥同步 event解决同步问题 上篇是解决子线程互斥问题
- 同步和互斥的问题
- 多线程的同步和互斥
- 同步和互斥的一些问题(死锁,优先级逆转)
- linux 命名信号量实现进程间的互斥与同步
- 【Linux多线程】同步与互斥的区别