//包含头文件
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
DESCRIPTION
The pthread_mutex_destroy() function shall destroy the mutex object referenced by mutex; the mutex object becomes, in
effect, uninitialized. An implementation may cause pthread_mutex_destroy() to set the object referenced by mutex to an
invalid value. A destroyed mutex object can be reinitialized using pthread_mutex_init(); the results of otherwise refer-
encing the object after it has been destroyed are undefined.
//pthread_mutex_destroy() 函数就是将一个互斥量销毁,变成一个没有经过初始化的值。这个函数的实现由可能导致互斥量
//成为一个无效的值。一个已经被销毁的互斥量可以重新被初始化,多次销毁的结果是未知的
It shall be safe to destroy an initialized mutex that is unlocked. Attempting to destroy a locked mutex results in
undefined behavior.
//如果一个互斥量已经初始化了,但是没有锁住,那么销毁它就是安全的操作。试图去销毁一个已经锁住的互斥量会
//导致未知的结果
The pthread_mutex_init() function shall initialize the mutex referenced by mutex with attributes specified by attr. If
attr is NULL, the default mutex attributes are used; the effect shall be the same as passing the address of a default
mutex attributes object. Upon successful initialization, the state of the mutex becomes initialized and unlocked.
//pthread_mutex_init()可以用指定的属性去初始化一个互斥量。如果给定的属性是空,那么会采用默认的属性。成功
//被初始化的互斥量是没有经过加锁的
Only mutex itself may be used for performing synchronization. The result of referring to copies of mutex in calls to
pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock(), and pthread_mutex_destroy() is undefined.
//互斥量是用来同步的,重复的调用一些关于互斥量的操作,结果是未知的
Attempting to initialize an already initialized mutex results in undefined behavior.
//试图去初始化一个已经初始化的互斥量会导致未知的结果
In cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize
mutexes that are statically allocated. The effect shall be equivalent to dynamic initialization by a call to
pthread_mutex_init() with parameter attr specified as NULL, except that no error checks are performed.
//可以用宏定义PTHREAD_MUTEX_INITIALIZER 去静态的初始化一个默认属性的互斥量
RETURN VALUE
If successful, the pthread_mutex_destroy() and pthread_mutex_init() functions shall return zero; otherwise, an error
number shall be returned to indicate the error.
//如果成功pthread_mutex_destroy() and pthread_mutex_init()返回0 ,失败会返回错误码
The [EBUSY] and [EINVAL] error checks, if implemented, act as if they were performed immediately at the beginning of
processing for the function and shall cause an error return prior to modifying the state of the mutex specified by
mutex.
//在进程的一开始就使用互斥量就会返回错误[EBUSY]
ERRORS
The pthread_mutex_destroy() function may fail if:
//pthread_mutex_destroy()会在一下情况下失败
EBUSY The implementation has detected an attempt to destroy the object referenced by mutex while it is locked or refer-
enced (for example, while being used in a pthread_cond_timedwait() or pthread_cond_wait()) by another thread.
//试图去销毁一个已经锁住的互斥量返回EBUSY
EINVAL The value specified by mutex is invalid.
//指定的互斥量无效
The pthread_mutex_init() function shall fail if:
//pthread_mutex_init() 会在以下情况失败
EAGAIN The system lacked the necessary resources (other than memory) to initialize another mutex.
//系统缺乏必要的资源(不是内存)去初始化互斥量
ENOMEM Insufficient memory exists to initialize the mutex.
//缺乏内存去初始化互斥量
EPERM The caller does not have the privilege to perform the operation.
//调用者没有权利去执行这项操作
The pthread_mutex_init() function may fail if:
//pthread_mutex_init() 还有可能因为下面的情况失败
EBUSY The implementation has detected an attempt to reinitialize the object referenced by mutex, a previously initial-
ized, but not yet destroyed, mutex.
//试图去重新初始化一个已经初始化的互斥量
EINVAL The value specified by attr is invalid.
//执行的属性值无效
These functions shall not return an error code of [EINTR].
//这个函数不会返回错误码EINTR
The following sections are informative.
六、互斥量实例
1、程序框图
2、源代码
点击(此处)折叠或打开
/*DATE:2015-4-1
*AUTHOR:WJ
*DESCRIPTION: 多线程访问变量产生错误的例子
*/
#include "apue.h"
struct student{
int id;
int age;
int name;
}stu;
//定义两个全局变量,因为两个线程都要访问
int i;
pthread_mutex_t mutex;
void *thread_fun1(void *arg)
{
while(1)
{
//加锁,对整个结构体访问进行加锁,防止产生错乱
pthread_mutex_lock(&mutex);
stu.id = i;
stu.age = i;
stu.name = i;
i++;
if(stu.id !=stu.age || stu.id !=stu.name || stu.age!=stu.name)
{
printf("thread 1 %d,%d,%d\n", stu.id, stu.age, stu.name);
break;
}
//访问变量完成,需要进行解锁,只有这样其他线程才能访问
pthread_mutex_unlock(&mutex);
}
return(void *)0;
}
void *thread_fun2(void *arg)
{
while(1)
{
//加锁,对整个结构体访问进行加锁,防止产生错乱
pthread_mutex_lock(&mutex);
stu.id = i;
stu.age = i;
stu.name = i;
i++;
if(stu.id!=stu.age || stu.id!=stu.name || stu.age!=stu.name)
{
printf("thread 2 %d,%d,%d\n", stu.id, stu.age, stu.name);
break;
}
pthread_mutex_unlock(&mutex);
}
return(void *)0;
}
int main()
{
pthread_t tid1, tid2;
int err;
//对互斥量进行初始化,只有初始化过到互斥量才能使用
err = pthread_mutex_init(&mutex, NULL);
if(err != 0)
{
printf("init mutex failed\n");
return;
}
//床在新线程
err = pthread_create(&tid1, NULL, thread_fun1, NULL);
if(err != 0)
{
printf("create new thread failed\n");
return;
}
//创造新线程
err = pthread_create(&tid2, NULL, thread_fun2, NULL);
if(err != 0)
{
printf("create new thread failed\n");
return;
}
//等待新线程运行结束
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
作业:使用多线程对一个队列进行增加和减少,增加操作是一个线程,删除操作是一个线程
点击(此处)折叠或打开
/*DATA: 2015-4-5
*AUTHOR; WJ
*DESCRIPTION: 将文件1.c 拷贝到11.c 12.c 13.c
*
*/
#include "apue.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct queue{
int len;
int write_pos;
int read_pos;
int data[50];
};
struct queue *queue_init()
{
struct queue *que;
//申请内存
que = (struct queue *)malloc(sizeof(struct queue));
if(que ==NULL)
{
printf("malloc failed\n");
return;
}
//初始化
que->len = 0;
que->write_pos = 0;
que->read_pos = 0;
return que;
}
void queue_destroy(struct queue *que)
{
//销毁互斥量和que
pthread_mutex_destroy(&mutex);
free(que);
}
void *queue_add(void *arg)
{
struct queue *que = (struct queue *)arg;
int buf=0;
while(buf<50)
{
pthread_mutex_lock(&mutex);
que->data[que->write_pos] = buf;
que->write_pos ++;
que->len ++;
buf++;
printf("write data %d to queue\n", que->data[que->write_pos -1]);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void *queue_del(void *arg)
{
struct queue *que = (struct queue *)arg;
int buf=0;
while(1)
{
sleep(2);
pthread_mutex_lock(&mutex);
buf = que->data[que->read_pos];
que->read_pos ++;
if(que->len -- == 0)
{
printf("queue is empty\n");
return;
}
buf++;
printf("read data %d from queue\n", que->data[que->read_pos -1]);
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid1, tid2;
int err;
struct queue *que;
//队列和锁都要初始化
que = queue_init();
err = pthread_mutex_init(&mutex, NULL);
if(err)
{
printf("mutex init failed\n");
free(que);
return;
}
err = pthread_create(&tid1, NULL, queue_add, (void *)que);
if(err)
{
printf("create add thread failed\n");
queue_destroy(que);
return;
}
err = pthread_create(&tid2, NULL, queue_del, (void *)que);
if(err)
{
printf("create del thread failed\n");
queue_destroy(que);
return;
}
//等待增加和删除操作完成
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
//销毁
queue_destroy(que);
}