mutex笔记

在多线程编程中, 为保证共享数据的完整性,引入互斥锁的概念,每个对象可以有一个mutex这样的标记,来标示这个对象在某一时刻只能被一个线程访问。

多线程程序一般使用互斥量来对临界区进行保护,临界区只允许加上互斥锁的那个线程来访问,其它的线程要等锁释放后重新加锁。

例如下面简单的程序,不加锁的情况下,任意线程都可以访问,导致a的值不可控制。

int get_a()
{
    a++;
    return a;
}

加锁之后,则同一时刻只会有一个线程访问。

int get_a() 
{
    lock(mutex);
    a++;
    unlock(mutex);
    return a;
}

这个接口则是线程安全的。

另外互斥锁还分为几种类型

  1. 普通锁
  2. 嵌套锁
  3. 纠错锁
  4. 自适应锁

下面用两个例子来说明一下普通锁和纠错锁。

编程时一般约定某个线程加的锁只能由自身来释放,但是普通锁可以解别的线程加的锁。

#include
#include
#include
#include
//静态方式创建
pthread_mutex_t tMutex = PTHREAD_MUTEX_INITIALIZER;
int count;

void *TdFunc(void *ptr)
{
  pthread_t tid;
  int i = *((int *)(ptr));
  int ret = 0;
  //获得线程自身的id
  tid = pthread_self();
  //将该线程的状态设为detached,则该线程运行结束后会释放所有资源。
  pthread_detach(tid);

  if (0 == i % 2) {
    printf("%u try to lock mutex\n", tid);
    ret = pthread_mutex_lock(&tMutex);
    if (0 == ret) {
      printf("%u lock mutex succ\n", tid);
    } else {
      printf("%u lock mutex failed\n", tid);
    }
  } else {
    printf("%u try to unlock mutex\n", tid);
    ret = pthread_mutex_unlock(&tMutex);
    if (0 == ret) {
      printf("%u try to unlock mutex succ\n", tid);
    } else {
      printf("%u unlock mutex failed\n", tid);
    }
  }
  count++;
}

int main(int argc, char *argv[])
{
  int i = 0;
  int ret = 0;
  //pthread不是linux系统默认的库,连接时需要使用静态库libthread.a
  for (i = 0; i < atoi(argv[1]); ++i) {
    pthread_t tid;
    printf("%u\n", tid);
    ret = pthread_create(&tid, NULL, TdFunc, &i);
    if (0 != ret) {
      strerror(ret);
      return 0;
    }
    sleep(1);
  }

  while(count < 5);
  return 0;
}

你可能感兴趣的:(mutex笔记)