c语言中锁的作用,c 互斥锁

互斥锁的作用保护共享数据: 在并发机制的情况下,有时候会有多个线程同时访问同一片数据,为了保护数据操作的准确性就需要通过加锁来进行保护。保持操作互斥: 可能一个程序会有多个操作,但是同一个时间只能有一个操作被执行,例如a/b两个操作,如果a被执行,b就不能被执行,同理b被执行,a就不能执行

操作函数pthread_mutex_t lock; /* 互斥锁定义 */

pthread_mutex_init(&lock, NULL); /* 动态初始化,成功返回0,失败返回非0 */

pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER; /* 静态初始化 */

pthread_mutex_lock(&lock); /* 阻塞的锁定互斥锁 */

pthread_mutex_trylock(&thread_mutex);/* 非阻塞的锁定互斥锁,成功获得互斥锁返回0,如果未能获得互斥锁,立即返回一个错误码 */

pthread_mutex_unlock(&lock); /* 解锁互斥锁 */

pthread_mutex_destroy(&lock) /* 销毁互斥锁 */

实例:保护共享数据第一个作用是保护共享的数据,在说明之前先看一下没有互斥锁保护的情况下,会发生什么样的状况,例子如下:#include 

#include 

#include 

#include 

#include 

static int g_count = 0;

static void *thread_fun_1(void *data)

{

g_count++;

printf("%s g_count: %d\n", __func__, g_count);

}

static void *thread_fun_2(void *data)

{

g_count++;

printf("%s g_count: %d\n", __func__, g_count);

}

static void *thread_fun_3(void *data)

{

g_count++;

printf("%s g_count: %d\n", __func__, g_count);

}

int main(int argc, char const *argv[])

{

pthread_t pid[3];

pthread_create(&pid[0], NULL, thread_fun_1, NULL);

pthread_create(&pid[1], NULL, thread_fun_2, NULL);

pthread_create(&pid[2], NULL, thread_fun_3, NULL);

pthread_join(pid[0], NULL);

pthread_join(pid[1], NULL);

pthread_join(pid[2], NULL);

return 0;

}

3个线程都会对g_count进行操作,没有任何保护的情况下,3个线程是存在竞争关系的,所以g_count最终可能会是1、2、3三种值中的一种,运行结果如下

202009091046301000001.jpg下面开始对数据进行保护,例子如下:#include 

#include 

#include 

#include 

#include 

static pthread_mutex_t g_mutex_lock;

static int g_count = 0;

static void *thread_fun_1(void *data)

{

pthread_mutex_lock(&g_mutex_lock);

g_count++;

printf("%s g_count: %d\n", __func__, g_count);

pthread_mutex_unlock(&g_mutex_lock);

}

static void *thread_fun_2(void *data)

{

pthread_mutex_lock(&g_mutex_lock);

g_count++;

printf("%s g_count: %d\n", __func__, g_count);

pthread_mutex_unlock(&g_mutex_lock);

}

static void *thread_fun_3(void *data)

{

pthread_mutex_lock(&g_mutex_lock);

g_count++;

printf("%s g_count: %d\n", __func__, g_count);

pthread_mutex_unlock(&g_mutex_lock);

}

int main(int argc, char const *argv[])

{

int ret;

pthread_t pid[3];

ret = pthread_mutex_init(&g_mutex_lock, NULL);

if (ret != 0) {

printf("mutex init failed\n");

return -1;

}

pthread_create(&pid[0], NULL, thread_fun_1, NULL);

pthread_create(&pid[1], NULL, thread_fun_2, NULL);

pthread_create(&pid[2], NULL, thread_fun_3, NULL);

pthread_join(pid[0], NULL);

pthread_join(pid[1], NULL);

pthread_join(pid[2], NULL);

pthread_mutex_destroy(&g_mutex_lock);

return 0;

}

对数据g_count的操作进行加锁之后,同一个时间只有一个线程能获取到锁,也就是只有一个线程能对g_count进行操作,保证了g_count的数据的准确性

实例:保持操作的互斥性有些情况下,2个不同的操作是不能同时进行的,例如fingerprint中的enroll和verify同一时间只能有一个操作进行。保持操作的互斥性本质上其实还是在保护共有的数据。看下下面的例子,打印hello的时候,world是无法打印的,如果希望打印world只能等待打印hello的线程退出之后再打印#include 

#include 

#include 

#include 

#include 

static pthread_mutex_t g_mutex_lock;

static void *thread_fun_1(void *data)

{

pthread_mutex_lock(&g_mutex_lock);

int i = 0;

while (i 

printf("hello\n");

i++;

sleep(1);

}

pthread_mutex_unlock(&g_mutex_lock);

}

static void *thread_fun_2(void *data)

{

pthread_mutex_lock(&g_mutex_lock);

int i = 0;

while (i 

printf("world\n");

i++;

sleep(1);

}

pthread_mutex_unlock(&g_mutex_lock);

}

static void do_print_hello()

{

pthread_t pth_id;

int result = pthread_create(&pth_id, NULL, thread_fun_1, NULL);

}

static void do_print_world()

{

pthread_t pth_id;

int result = pthread_create(&pth_id, NULL, thread_fun_2, NULL);

}

int main(int argc, char const *argv[])

{

int ret;

int cid;

ret = pthread_mutex_init(&g_mutex_lock, NULL);

if (ret != 0) {

printf("mutex init failed\n");

return -1;

}

while (1) {

scanf("%d", &cid);

getchar();

switch (cid) {

case 0:

do_print_hello();

break;

case 1:

do_print_world();

break;

default:

break;

}

}

pthread_mutex_destroy(&g_mutex_lock);

return 0;

}

上面的互斥锁是阻塞式的锁,也可以通过非阻塞式的锁进行,看下面的例子,pthread_mutex_trylock()函数如果获取到互斥锁了,会返回0,如果没有获取的互斥锁,会立即返回一个非0值,例子中通过g_cancel来通知线程进行退出,如果当前正在打印hello,发出打印world命令之后,通过pthread_mutex_trylock()就能知道当前有没有打印线程正在运行,如果有在运行的线程,通过置位g_cancel来退出正在运行的线程#include 

#include 

#include 

#include 

#include 

static pthread_mutex_t g_mutex_lock;

static int g_cancel = 0;

static void *thread_fun_1(void *data)

{

if (pthread_mutex_trylock(&g_mutex_lock) != 0) {

g_cancel = 1;

return 0;

}

int i = 0;

g_cancel = 0;

while (i 

if (g_cancel) break;

printf("hello\n");

i++;

sleep(1);

}

pthread_mutex_unlock(&g_mutex_lock);

}

static void *thread_fun_2(void *data)

{

if (pthread_mutex_trylock(&g_mutex_lock) != 0) {

g_cancel = 1;

return 0;

}

int i = 0;

g_cancel = 0;

while (i 

if (g_cancel) break;

printf("world\n");

i++;

sleep(1);

}

pthread_mutex_unlock(&g_mutex_lock);

}

static void do_print_hello()

{

pthread_t pth_id;

int result = pthread_create(&pth_id, NULL, thread_fun_1, NULL);

}

static void do_print_world()

{

pthread_t pth_id;

int result = pthread_create(&pth_id, NULL, thread_fun_2, NULL);

}

int main(int argc, char const *argv[])

{

int ret;

int cid;

ret = pthread_mutex_init(&g_mutex_lock, NULL);

if (ret != 0) {

printf("mutex init failed\n");

return -1;

}

while (1) {

scanf("%d", &cid);

getchar();

switch (cid) {

case 0:

do_print_hello();

break;

case 1:

do_print_world();

break;

default:

break;

}

}

pthread_mutex_destroy(&g_mutex_lock);

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值