C语言之简单使用互斥锁实现并发控制操作
Posted 你是小KS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言之简单使用互斥锁实现并发控制操作相关的知识,希望对你有一定的参考价值。
当前版本:eclipse c++
、MinGW-W64-builds-4.3.5
、widnwos
1. 声明
当前内容主要为测试使用互斥锁实现并发控制效果,分析C语言中线程并发
2. 不加锁的并发代码
#include <stdio.h>
#include <stdlib.h>
// 从unistd中导入sleep函数
#include<unistd.h>
// 导入需要使用的线程库
#include <pthread.h>
/**
* @description 当前内容主要为测试多线程访问同一个变量的操作,测试并发问题
* @author hy
* @createTime 2022-04-16
*/
void startThread(void *(*run)(void *), void *arg);
int shutdownNum = 3;
static int modifyNum = 0; // 一个全局的共享变量
int defaultSleepTime = 50;
int executeNum = 5;
// 定义互斥锁标记
//pthread_mutex_t lock;
void lockAndIncreament()
//pthread_mutex_lock(&lock);
modifyNum += 1;
//pthread_mutex_unlock(&lock);
// 这里表示一个线程
void* run1(void* arg)
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
// 执行特定次打印就结束
while (num < executeNum)
//lockAndIncreament();
modifyNum+=1;
++num;
//pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
//pthread_mutex_unlock(&lock);
fflush(stdout);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
void* run2(void* arg)
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
// 执行特定次打印就结束
while (num < executeNum)
//lockAndIncreament();
modifyNum+=1;
++num;
//pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
//pthread_mutex_unlock(&lock);
fflush(stdout);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
void* run3(void* arg)
// 得到当前执行的线程的执行id
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
// 执行特定次打印就结束
while (num < executeNum)
//lockAndIncreament();
modifyNum+=1;
++num;
//pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
//pthread_mutex_unlock(&lock);
fflush(stdout);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
void* run4(void* arg)
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
while (num < executeNum)
//lockAndIncreament();
modifyNum+=1;
++num;
//pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
//pthread_mutex_unlock(&lock);
fflush(stdout);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
int main(int argc, char **argv)
void *(*func1)(void *) = run1;
void *(*func2)(void *) = run2;
void *(*func3)(void *) = run3;
void *(*func4)(void *) = run4;
char* arg1[2] = "thread-1" ;
void* args1 = arg1; // 使用携带正确参数的可以执行,否则认为不可执行
printf("before create thread\\n");
char* arg2[2] = "thread-2" ;
void* args2 = arg2;
char* arg3[2] = "thread-3" ;
void* args3 = arg3;
char* arg4[2] = "thread-4" ;
void* args4 = arg4;
// 启动三个线程,执行不同的方法(如果执行的方法相同则不会出现并发?)
// 解决多线程问题
// 1. 初始化互斥锁
//pthread_mutex_init(&lock, NULL);
startThread(func1, args1);
startThread(func2, args2);
startThread(func3, args3);
startThread(func4, args4);
//startThread(func1, args1);
// startThread(func1, args2);
// startThread(func1, args3);
printf("after create thread\\n");
while (shutdownNum > 0)
//printf("main thread wait! shutdownNum = %d\\n",shutdownNum);
//fflush(stdout);
sleep(1);
printf("main thread shutdown!\\n");
printf("modifyNum = %d", modifyNum);
// 销毁互斥锁
//pthread_mutex_destroy(&lock);
return 0;
// 表现为启动一个线程,给定一个函数和参数
void startThread(void *(*run)(void *), void *arg)
pthread_t th;
const pthread_attr_t *attr = NULL;
void *(*func)(void *) = run;
int result = pthread_create(&th, attr, func, arg);
if (result != 0)
// 表示无法创建该线程
printf("can't create thread in current application!");
exit(-1);
// 表现为join操作,即线程必定阻塞主线程执行,&res表示将返回结果拿到
//pthread_join(th, res);
执行结果(有部分情况下会出现如下效果,多次测试后才会出现)
并发就是有竞争,导致得到的结果不正确,这里结果应该是20
3. 将锁控制打开后
一般对于竞争的变量加入读保护和写保护就可以了(防止并发中写入或者读取不正确)
#include <stdio.h>
#include <stdlib.h>
// 从unistd中导入sleep函数
#include<unistd.h>
// 导入需要使用的线程库
#include <pthread.h>
/**
* @description 当前内容主要为测试多线程访问同一个变量的操作,测试并发问题
* @author hy
* @createTime 2022-04-16
*/
void startThread(void *(*run)(void *), void *arg);
int shutdownNum = 3;
static int modifyNum = 0; // 一个全局的共享变量
int defaultSleepTime = 50;
int executeNum = 5;
// 定义互斥锁标记
pthread_mutex_t lock;
void lockAndIncreament()
pthread_mutex_lock(&lock);
modifyNum += 1;
pthread_mutex_unlock(&lock);
// 这里表示一个线程
void* run1(void* arg)
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
// 执行特定次打印就结束
while (num < executeNum)
lockAndIncreament();
//modifyNum+=1;
++num;
pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
fflush(stdout);
pthread_mutex_unlock(&lock);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
void* run2(void* arg)
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
// 执行特定次打印就结束
while (num < executeNum)
lockAndIncreament();
//modifyNum+=1;
++num;
pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
fflush(stdout);
pthread_mutex_unlock(&lock);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
void* run3(void* arg)
// 得到当前执行的线程的执行id
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
// 执行特定次打印就结束
while (num < executeNum)
lockAndIncreament();
//modifyNum+=1;
++num;
pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
fflush(stdout);
pthread_mutex_unlock(&lock);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
void* run4(void* arg)
char* thread_name = NULL;
// 校验参数数量和参数个数
if (!arg || arg <= 0)
printf("exit with error!\\n");
shutdownNum--;
// 将参数的值进行赋值操作
pthread_exit("arg len <= 0");
else
thread_name = ((char**) arg)[0];
int num = 0;
while (num < executeNum)
lockAndIncreament();
//modifyNum+=1;
++num;
pthread_mutex_lock(&lock);
printf("print %s : modifyNum : %d\\n", thread_name, modifyNum);
fflush(stdout);
pthread_mutex_unlock(&lock);
// 表示使用打印为1秒每次sleep(1);
sleep(1); //表示休眠200毫秒
printf("%s exit!\\n", thread_name);
fflush(stdout);
shutdownNum--;
pthread_exit("num >5");
return NULL;
int main(int argc, char **argv)
void *(*func1)(void *) = run1;
void *(*func2)(void *) = run2;
void *(*func3)(void *) = run3;
void *(*func4)(void *) = run4;
char* arg1[2] = "thread-1" ;
void* args1 = arg1; // 使用携带正确参数的可以执行,否则认为不可执行
printf("before create thread\\n");
char* arg2[2] = "thread-2" ;
void* args2 = arg2;
char* arg3[2] = "thread-3" ;
void* args3 = arg3;
char* arg4[2] = "thread-4" ;
void* args4 = arg4;
以上是关于C语言之简单使用互斥锁实现并发控制操作的主要内容,如果未能解决你的问题,请参考以下文章