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编程:互斥锁条件变量
条件变量:等待与信号发送 使用互斥锁虽然可以解决一些资源竞争的问题,但互斥锁只有两种状态(加锁和解锁),这限制了互斥锁的用途. 条件变量(条件锁)也可以解决线程同步和共享资源访问的问题,条件变量是对互 ...
随机推荐
- java web 分页实现
分页实现的效果: ///////// /////////////////////////////////////////////////////// /////////////////// ...
- Cache和Buffer的区别(转载)
1. Cache:缓存区,是高速缓存,是位于CPU和主内存之间的容量较小但速度很快的存储器,因为CPU的速度远远高于主内存的速度,CPU从内存中读取数据需等待很长的时间,而 Cache保存着CPU刚 ...
- 【VBA】获取模板保存的路径
使用VBA如何获取模板保存的路径呢?具体代码如下: Sub 获取Excle模板保存路径() MsgBox "获取Excle模板保存路径:" & Application.Te ...
- 51单片机 | 基于I2C总线的秒表模拟应用
———————————————————————————————————————————— 参考地址: http://blog.csdn.net/junyeer/article/details/4648 ...
- Codeforces548E:Mike and Foam
Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a special shelf. There are n ...
- 调用iPhone的短信
不传递短信内容,可以调用下面的方法: [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://4664 ...
- PHP面试题及答案解析(5)—数据结构与算法
1.使对象可以像数组一样进行foreach循环,要求属性必须是私有.(Iterator模式的PHP5实现,写一类实现Iterator接口) <?php class Test implements ...
- 深入探析 Rational AppScan Standard Edition 新特性之 Glass Box 扫描
众所周知,Web 应用安全测试通常有黑盒安全测试和白盒安全测试两种方法.这两种方法孰优孰劣一直众议纷纷.广为公认的是,这两种测试方法有着良好地互补性,两种测试方法的结合是未来安全测试技术的发展趋势.G ...
- Android IntentService全然解析 当Service遇到Handler
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/47143563: 本文出自:[张鸿洋的博客] 一 概述 大家都清楚.在Andro ...
- Win7 设置、访问共享文件夹
一.设置共享文件夹 右键点击文件夹,打开“属性”窗口,选择“共享”选项卡 点击“共享”按钮,打开“文件共享”窗口,在下拉列表中选择账户,点“添加”,最后点“共享”按钮. 二.访问 \\192.168. ...