互斥量进行同步
另一种用在多线程程序中的访问方法是使用互斥量。它允许 程序员锁住某个对象,使得每次只能有一个线程访问他。
为了控制对关键代码的访问,必须在进入代码之前锁住一个互斥量,然后在完成操作之后解锁它。
下面用实例来说明,本实例是经典的多线程程序,线程1接受输入字符,线程2统计字符数。它们共享一个
公共的工作区
实例:
//初始化互斥量
if(pthread_mutex_init(&work_mutex,0)!=0)
{
perror("mutex initialization failed");
exit (1);
}
//创建新的线程
if(pthread_create(&a_thread,NULL,thread_fun,NULL)!=0)
{
perror("thread create failed");
exit (1);
}
//给工作区枷锁,
res=pthread_mutex_lock(&work_mutex);
if(res!=0)
{
perror("mutex lock failed");
exit (1);
}
printf("input some text.enter 'end' to finish/n");
//读文本
while(!time_to_exit)
{
fgets(work_area,WORK_SIZE,stdin);//从标准输入读到工作区
//解锁,允许新线程访问他并统计字符数目
res=pthread_mutex_unlock(&work_mutex);
if(res!=0)
{
perror("mutex lock failed");
exit (1);
}
while(1)
{
//枷锁
res=pthread_mutex_lock(&work_mutex);
if(res!=0)
{
perror("mutex lock failed");
exit (1);
}
if(work_area[0]!='/0')
{
//解锁
res=pthread_mutex_unlock(&work_mutex);
if(res!=0)
{
perror("mutex unlock failed");
exit (1);
}
sleep(1);
}
else
break;
}
}
//解锁
res=pthread_mutex_unlock(&work_mutex);
if(res!=0)
{
perror("mutex unlock failed");
exit (1);
}
puts("/nwaiting for thread to finished.../n");
if(pthread_join(a_thread,&thread_result))
{
perror("thread join failed");
exit (1);
}
printf("joined,it returned %s/n",(char *)thread_result);
//销毁互斥量所占用的资源
pthread_mutex_destroy(&work_mutex);
return 0;
}
void *thread_fun(void *arg)
{
int res;
sleep(1);
res=pthread_mutex_lock(&work_mutex);
if(res!=0)
{
perror("mutex lock failed");
exit (1);
}
while(strncmp("end",work_area,3)!=0)
{
//统计字符个数
printf("you input %d characters/n",strlen(work_area)-1);
work_area[0]='/0';
res=pthread_mutex_unlock(&work_mutex);
if(res!=0)
{
perror("mutex unlock failed");
exit (1);
}
sleep(1);//等待主线程继续运行
res=pthread_mutex_lock(&work_mutex);
if(res!=0)
{
perror("mutex lock failed");
exit (1);
}
while(work_area[0]=='/0')
{
/*周期行给互斥量枷锁,加锁成功,检查主线程是否有字符送来处理,没有解锁互斥量
继续等待;如果有,统计字符个数,再次进入循环
*/
res=pthread_mutex_unlock(&work_mutex);
if(res!=0)
{
perror("mutex unlock failed");
exit (1);
}
sleep(1);//等待主线程继续运行
res=pthread_mutex_lock(&work_mutex);
if(res!=0)
{
perror("mutex lock failed");
exit (1);
}
}
}
time_to_exit = 1;
work_area[0] = '/0';
res=pthread_mutex_unlock(&work_mutex);
if(res!=0)
{
perror("mutex unlock failed");
exit (1);
}
pthread_exit("OK!");
}
运行结果:
[sea@localhost ~]$ ./threadtest1
input some text.enter 'end' to finish
zhanghaiyang
you input 12 characters
zhang
you input 5 characters
这种通过轮询来获得结果的方法通常并不是好的编程方式,在实际的编程中,应该尽可能用信号量来避免出现这种情况