互斥:
简单的理解就是一个县城进入工作区之后,如果有其他的线程想要进入工作区,他就会进入等待状态,要等待工作区内的线程结束后才可以进入。
基本函数:
(1)pthread_mutex_init()函数
原型: int pthread_mutex_init(phread_mutex_t *mutex,const pthread_mutexattr_t * attr);
描述:设置互斥性的属性
参数:第一个参数:预先声明的pthread_mutex_t 对象指针
第二个参数:互斥锁属性,null 表示使用默认属性
返回值:成功时返回0,失败时1返回一个错误代码
(2)pthread_mutex_lock()
原型: int pthread_mutex_lock(pthread_mutex_t * mutex);
描述:pthread_mutex_lock返回时,互斥锁被锁定,如果这个互斥锁被一个线程锁定和拥有,那么另一个线程要调用这个函数会进入拥塞状态(即等待状态),直到互斥锁被释放为止。
返回值:成功时,返回0 ,失败时 返回错误代码
(3)pthread_mutex_unlock()函数
原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
描述:释放互斥锁
返回值:成功时返回0,失败时返回一个错误代码
(4)pthread_mutex_destroy()函数
原型:int pthread_mutex_destroy(pthread_mutex_t * mutex);
描述:删除互斥锁
返回值:成功时返回0 ,失败时返回错误代码
实例:
lock.c文件
描述:这个程序主要可以概括为主线程负责接受输入的字符串,而子线程负责统计并输出字符数。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaohore.h>
void *thread_function(void * arg);
pthread_mutex_t work_mutex;//创建一个线程变量
#define work_size 1024
char work_area[work_size];
int time_to_exit = 0;
int main()
{
int res;
pthread_t a_thread;
void * thread_result;
//初始化互斥量
res = pthread_mutex_init(&work_mutex,NULL);
if(res != 0)
{
printf("互斥量初始化失败 ");
exit(EXIT_FAILURE);
}
//启动新的线程
res = pthread_create(&a_thread, NULL, thread_function ,NULL);
if(res !=0 )
{
perror("线程创建失败 ");
exit(1);
}
pthread_mutex_lock(&work_mutex);
printf("请输入一些文本,输入end 结束: ");
while(! time_to_exit)
{
fgets(work_area,work_size,stdin);
pthread_mutex_unlock(&work_mutex);
while(1)
{
pthread_mutex_lock(&work_mutex);
if(work_area[0]!= ' ')
{
pthread_mutex_unlock(&work_mutex);
sleep(1)
}
else
{
break;
}
}
}
pthread_mutex_unlock(&work_mutex);
printf("等待线程结束:...
");
res = pthread_join(a_thread,&thread_result);
if(res != 0 )
{
perror("thread join failed ");
exit(1);
}
printf("thread oined ");
pthread_mutex_destroy(&work_mutex);
exit(1);
}
//主线程首先锁定工作区,在获取输入的字符串后,释放工作区,让其它线程对字符个数进行统计。work_area[0]为字符为空时表示统计结束。通过周期性的对互斥量进行枷锁,检查是否已经统计完。
//在线程中要执行的代码
void *thread_function(void * arg)
{
sleep(1);
pthread_mutex_lock(&work_mutex);
while(strcmp("end",work_area,3)! = 0)
{
printf("你输入了%d个字符 ",strlen(work_area)-1);
work_area[0]= ' ';
pthread_mutex_unlock(&work_mutex);
while(work_area[0]==' ')
{
thread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
}
}
time_to_exit = 1;
work_area[0] = ' ';
pthread_mutex_unlock(&work_mutex);
pthread_exit(0);
}
在新进程一上来之前先试图对互斥量加锁。如果他已经被锁上,新线程就会进入堵塞状态直到互斥锁释放为止,一旦可以进入工作区。
就首先检查是否有退出请求(end)如果有,就设置time_to_exit变量和work_area,然后退出程序。
如果没有退出,那么就对字符个数进行统计,把work_area[0]设置为空,表示统计工作完成,接下来就释放互斥锁,等待主线程的运行,周期性地给互斥量加锁,如果加锁成功,就检查主线程是否又给我们新的字符串统计。如果没有,就释放互斥锁继续等待。