linux c编程:线程互斥一
当多个线程共享相同的内存的时候,需要确保每个线程都看到一致的数据视图。如果每个线程使用的变量都是其他线程不会读取和修改的。那么就不存在一致性问题。同样,如果变量是只读的,多个线程也不会有一致性的问题。但是当一个线程可以修改的变量其他线程也可以读取或者修改的时候。我们就需要对这些线程进行同步,确保它们在访问变量存储内容时不会访问到无效的值。
首先来看一个线程不同步的例子:
typedef struct foo_test{
int count;
int i;
}foo_test;
void mutex_try(foo_test *f){
pthread_t tid;
while (f->i<20){
tid=pthread_self();
f->count+=1;
printf("the thread id is %d,i is %d,count is %d\n",tid,f->i,f->count);
f->i++;
}
pthread_exit((void *)2);
}
int main()
{
foo_test f;
pthread_t tid1,tid2;
void *tret;
f.count=0;
f.i=0;
pthread_create(&tid1,NULL,mutex_try,&f);
pthread_create(&tid2,NULL,mutex_try,&f);
pthread_join(tid1,&tret);
printf("thread 1 exit code %ld\n",(long)tret);
pthread_join(tid2,&tret);
printf("thread 2 exit code %ld\n",(long)tret);
return 0;
}
运行结果:可以看到当thread1的计数为1的时候,count值从1变成了3,正常应该是2.这是因为thread2在 i=0的时候也对count值增加了1, 因此当thread1在i=1访问的时候,count值就变成了3. 在这里两个线程访问了两次i=0. 这就是不同步导致的

为了解决这个问题,在线程中就必须用到锁,同一时间只允许一个线程访问该变量。也就是修改操作是原子操作。这样就不会存在竞争。可以使用pthread的互斥接口来保护数据,确保同一时间只有一个线程访问数据。互斥从本质上就是一把锁,在访问共享资源前对互斥量进行设置(加锁),在访问完成后释放互斥量(解锁)
互斥变量是用pthread_mutex_t数据类型表示的,在使用互斥变量以前,必须首先对它进行初始化,可以把它设置为常量PTHREAD_MUTEX_INITIALIZER(只适用于静态分配的互斥量),也可以通过调用pthread_mutex_init函数进行初始化,如果动态分配互斥量例如通过malloc调用。在释放内存前需要调用pthread_mutex_destroy。
代码修改如下:
typedef struct foo_test{
int count;
pthread_mutex_t f_lock;
int i;
}foo_test;
void mutex_try(foo_test *f){
pthread_t tid;
while (f->i<20){
tid=pthread_self();
pthread_mutex_lock(&f->f_lock);
f->count+=1;
f->i++;
pthread_mutex_unlock(&f->f_lock);
printf("the thread id is %d,i is %d,count is %d\n",tid,f->i,f->count);
// Sleep(1000);
}
pthread_exit((void *)2);
}
int main()
{
foo_test *f;
pthread_t tid1,tid2;
void *tret;
f=(foo_test *)malloc(sizeof(foo_test));
f->count=0;
f->i=0;
pthread_mutex_init(&f->f_lock,NULL);
pthread_create(&tid1,NULL,mutex_try,f);
pthread_create(&tid2,NULL,mutex_try,f);
pthread_join(tid1,&tret);
printf("thread 1 exit code %ld\n",(long)tret);
pthread_join(tid2,&tret);
printf("thread 2 exit code %ld\n",(long)tret);
return 0;
}
运行结果如下:可以看到两个线程对于变量i的使用没有重复的了。i的增加可以保持原子性。同理count也是一样

linux c编程:线程互斥一的更多相关文章
- linux c编程 -- 线程互斥
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h& ...
- linux系统编程--线程同步
同步概念 所谓同步,即同时起步,协调一致.不同的对象,对“同步”的理解方式略有不同. 如,设备同步,是指在两个设备之间规定一个共同的时间参考: 数据库同步,是指让两个或多个数据库内容保持一致,或者按需 ...
- Linux系统编程——线程私有数据
在多线程程序中.常常要用全局变量来实现多个函数间的数据共享.因为数据空间是共享的,因此全局变量也为全部线程共同拥有. 測试代码例如以下: #include <stdio.h> #inclu ...
- linux系统编程--线程
安装线程man page,命令:sudo apt-get install manpages-posix-dev 线程概念 什么是线程 LWP:light weight process 轻量级的进程,本 ...
- Linux C多线程编程-线程互斥
Linux下的多线程编程需要注意的是程序需要包含头文件pthread.h,在生成可执行文件的时候需要链接库libpthread.a或者libpthread.so. 线程创建函数: pthread_cr ...
- Linux多任务编程——线程
线程基础 △ 由于进程的地址空间是私有的,因此在进行上下文切换时,系统开销比较大 △ 在同一个进程中创建的线程共享该进程的地址空间 △ 通常线程值得是共享相同地址空间的多个任务 △ 每个线程的私有这些 ...
- Linux多线程编程——线程的创建与退出
POSIX线程标准:该标准定义了创建和操纵线程的一整套API.在类Unix操作系统(Unix.Linux.Mac OS X等)中,都使用Pthreads作为操作系统的线程.Windows操作系统也有其 ...
- Linux系统编程 —线程同步概念
同步概念 同步,指对在一个系统中所发生的事件之间进行协调,在时间上出现一致性与统一化的现象. 但是,对于不同行业,对于同步的理解略有不同.比如:设备同步,是指在两个设备之间规定一个共同的时间参考:数据 ...
- linux多线程编程之互斥锁
多线程并行运行,共享同一种互斥资源时,需要上互斥锁来运行,主要是用到pthread_mutex_lock函数和pthread_mutex_unlock函数对线程进行上锁和解锁 下面是一个例子: #in ...
- linux c编程:互斥锁条件变量
条件变量:等待与信号发送 使用互斥锁虽然可以解决一些资源竞争的问题,但互斥锁只有两种状态(加锁和解锁),这限制了互斥锁的用途. 条件变量(条件锁)也可以解决线程同步和共享资源访问的问题,条件变量是对互 ...
随机推荐
- [Algorithm] Maximum Contiguous Subarray algorithm implementation using TypeScript / JavaScript
Naive solution for this problem would be caluclate all the possible combinations: const numbers = [1 ...
- 往MySQL数据库datetime类型字段中插入数据库的当前时间
代码: StringBuilder sb = new StringBuilder(); sb.append(" insert into uosdetailfile ("); sb. ...
- native method与so中function的关联
在Android中,可以通过JNI的方式来调用和访问用C/C++实现的代码,这些代码以SharedLibrary的方式存在于so中.从Java Code到Native Code的一般使用过程为: 在J ...
- android:Cordova Android, hello Cordova ,PhoneGap android
文章来自:http://blog.csdn.net/intbird 官方文档: http://cordova.apache.org/docs/en/5.0.0//index.html intbird的 ...
- XQuery获取节点的属性名与值
e.g: DECLARE @xmlSource XML SET @xmlSource = '<t topA="1"> <a x="2" z=& ...
- 高速排序java语言实现
本博客不再更新,很多其它精彩内容请訪问我的独立博客 高速排序是非常重要的排序算法,可是我在学的时候发现网上没有特别好的样例所以自己动手写了一个. 自己动手丰衣足食. package sort; imp ...
- Git简明操作
我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下 ...
- 常用的二种修改mysql最大连接数的方法
方法一:进入MYSQL安装目录 打开MYSQL配置文件 my.ini 或 my.cnf查找 max_connections=100 修改为 max_connections=1000 服务里重起MY ...
- react native使用 mobx , can't find variable:Symbol
原因是因为 mobx的版本用的最新版本..用到了 Symbol部分es6的api特性. 解决问题办法 1. 把mobx降版本到 4.3.1 . mobx-react降版本到 5.1.0 即可. 或者 ...
- Hbase笔记3 shell命令
http://www.jb51.net/article/31172.htm 这个文章写得挺好 1.HBase的shell就和我们用Mysql的终端是一个意思,比如我们安装好Mysql,配置好了环境变量 ...