linux 只运行一个实例 互斥锁,Linux多线程4-1_互斥量

//包含头文件

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、程序框图

36148c683053b33c3239180ad989d872.png

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);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值