互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源。可以保证以下三点:
原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一个线程
锁定了一个互斥量,没有其他线程在同一时间可以成功锁定这个互斥量。
唯一性:如果一个线程锁定了一个互斥量,在它解除锁定之前,没有其他线程可以锁定这个互斥量。
非繁忙等待:如果一个线程已经锁定了一个互斥量,第二个线程又试图去锁定这个互斥量,则第二个线程将
被挂起(不占用任何cpu资源),直到第一个线程解除对这个互斥量的锁定为止,第二个线程则被唤
醒并继续执行,同时锁定这个互斥量。
从以上三点,我们看出可以用互斥量来保证对变量(关键的代码段)的排他性访问。
from http://blog.chinaunix.net/uid-21411227-id-1826888.html
从网上找的代码,但是自己还不是很能理解。所以根据这个代码进行研究分析。。。
下面的代码 from http://blog.csdn.net/hitwengqi/article/details/8015646
#include <stdio.h>
#include <Windows.h>
#include<iostream>
#include <pthread.h>
#pragma comment(lib, "pthreadVC2.lib") //必须加上这句
using namespace std;
#define NUM_THREADS 5
int sum = 0;//定义个全局变量,让所有线程进行访问,这样就会出现同时写的情况,势必会需要锁机制;
pthread_mutex_t sum_mutex;
void* say_hello(void* args)
{
cout << "hello in thread " << *((int *)args) << endl;
pthread_mutex_lock (&sum_mutex);//修改sum就先加锁,锁被占用就阻塞,直到拿到锁再修改sum;
cout << "before sum is " << sum << " in thread " << *((int *)args) << endl;
sum += *((int *)args);
cout << "after sum is " << sum << " in thread " << *((int *)args) << endl;
pthread_mutex_unlock (&sum_mutex);//完事后解锁,释放给其他线程使用;
pthread_exit(0);//退出随便扔个状态码
return NULL;
}
int main()
{
pthread_t tids[NUM_THREADS];
int indexes[NUM_THREADS];
//下三句是设置线程参数,但是没明白有什么必要性。。。。
pthread_attr_t attr; //线程属性结构体,创建线程时加入的参数
pthread_attr_init(&attr); //初始化
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); //是设置你想要指定线程属性参数,这个参数表明这个线程是可以join连接的,join功能表示主程序可以等线程结束后再去做某事,实现了主程序和线程同步功能
pthread_mutex_init (&sum_mutex, NULL);//这句是对锁进行初始化,必须的;
for(int i = 0; i < NUM_THREADS; ++i)
{
indexes[i] = i;
int ret = pthread_create( &tids[i], &attr, say_hello, (void *)&(indexes[i]) );//5个进程你们去修改sum吧哈哈;
if (ret != 0)
{
cout << "pthread_create error: error_code=" << ret << endl;
}
}
pthread_attr_destroy(&attr);//删除参数变量
void *status;
for (int i = 0; i < NUM_THREADS; ++i)
{
int ret = pthread_join(tids[i], &status);
if (ret != 0)
{
cout << "pthread_join error: error_code=" << ret << endl;
}
}
cout << "finally sum is " << sum << endl;
pthread_mutex_destroy(&sum_mutex);//注销锁,可以看出使用pthread内置变量神马的都对应了销毁函数,估计是内存泄露相关的吧;
system("pause");
return 0;
}
运行结果如下:
hello in thread hello in thread 1hello in thread 3hello in thread 2hello in thre
ad 40
before sum is 0
in thread 4
after sum is 4
in thread 4
before sum is 4 in thread 2
after sum is 6 in thread 2
before sum is 6 in thread 1
after sum is 7 in thread 1
before sum is 7 in thread 3
after sum is 10 in thread 3
before sum is 10 in thread 0
after sum is 10 in thread 0
finally sum is 10
请按任意键继续. . .
//多线程的顺序是混乱的,混乱就是正常;只要sum访问及修改是正常的,就达到多线程的目的了,运行顺序不能作为参照;