下面我们来看看这个demo

#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

#include <stdlib.h>

int myglobal;

void * thread_function(void * arg)

{

int i,j;

for (i=0; i<20; i++) {

j=myglobal;

j++;

printf(".");

fflush(stdout);

sleep(1);

myglobal=j;

}

return  NULL;

}

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

{

pthread_t mythread;

int i;

if (pthread_create(&mythread, NULL, thread_function, NULL)) {

printf("error creating thread");

abort();

}

for (i=0; i<20; i++) {

myglobal++;

printf("o");

fflush(stdout);

sleep(1);

}

if (pthread_join(mythread, NULL)) {

printf("error joining thread");

abort();

}

printf("\nmyglobal equals %d\n",myglobal);

return 0;

}

对于这个问题,我们知道是这个全局变量没有保护的问题,这样导致一个线程的更改覆盖了另外一个线程的改变。
那下面我们就对这个全局变量myglobal加锁。即在myglobal的范围上下加上lock和unlock,具体如下:

#include <stdio.h>

#include <pthread.h>

#include <unistd.h>

#include <stdlib.h>

int myglobal;

pthread_mutex_t mymutex=PTHREAD_MUTEX_INITIALIZER;

void * thread_function(void * arg)

{

int i,j;

for (i=0; i<20; i++) {

pthread_mutex_lock(&mymutex);

j=myglobal;

j++;

printf(".");

fflush(stdout);

sleep(1);

myglobal=j;

pthread_mutex_unlock(&mymutex);

}

return  NULL;

}

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

{

pthread_t mythread;

int i;

if (pthread_create(&mythread, NULL, thread_function, NULL)) {

printf("error creating thread");

abort();

}

for (i=0; i<20; i++) {

pthread_mutex_lock(&mymutex);

myglobal++;

pthread_mutex_unlock(&mymutex);

printf("o");

fflush(stdout);

sleep(1);

}

if (pthread_join(mythread, NULL)) {

printf("error joining thread");

abort();

}

printf("\nmyglobal equals %d\n",myglobal);

return 0;

}

对于线程的运行我们一定不要假设哪个会在前面运行哪个会在后面运行,只要线程创建以后我们可以认为他们是同时运行的。

我们看下互斥对象的使用。

首先是初始化

静态初始化给变量赋一个常数

pthread_mutex_t mymutex=PTHREAD_MUTEX_INITIALIZER;

另外也可以动态的创建互斥对象,即像使用malloc一样动态分配,在这边我们使用

int pthread_mutex_init(pthread_mutex_t *restrict, const pthread_mutexattr_t *restrict)

第一个参数是要初始化的互斥对象,这个指针已经分配好了一块内存,第二个参数是设定互斥量属性的,为空则为默认属性。

如果使用了pthread_mutex_init初始化了互斥对象,就要用pthread_mutex_destory来销毁,其参数为指向要销毁的互斥量。注意的是这边不会释放用来存储互斥量pthread_mutex_t的内存,也就是我们可以直接再用pthread_mutex_init来重新初始化被销毁的内存。

另外我们要注意的是不管是创建还是销毁,成功的时候返回的都是0.

使用

pthread_mutex_lock接受一个互斥对象的指针作为参数,将其锁定,如果该互斥对象已经锁定,则该调用者进入睡眠状态,如果函数返回,则唤醒当前线程。

pthread_mutex_unlock与上述配合使用,看到名字我们知道这个是解锁。

这里我们要明确的是一定要尽快对已经加锁的互斥对象进行解锁,以提高性能。

另外一定不要对没有加锁的互斥对象进行解锁,这样pthread_mutex_unlock会调用失败。

我们会考虑下一个问题就是,计算机要不停的监测这个互斥量的状态,改变状态之后要立即做出反应,这样是不可取的,因此也就是有了信号量这一说。

通过信号量来使线程进入睡眠状态或者唤醒这个线程。

最新文章

  1. Jquery-zTree的用法
  2. quick-cocos2d-x :加入精灵背景
  3. FUND
  4. PHPstudy和ecshop的安装和使用
  5. http://www.oreilly.com/catalog/errataunconfirmed.csp?isbn=9780596529321
  6. mysql中连接失败2003错误解决办法
  7. IOS 多级列表展开控件
  8. 定位相关-CLLocationManager的使用。
  9. nginx配置中文域名解析
  10. DataGridView减少闪烁的解决办法
  11. 如何实现View上添加标签
  12. 主题模型-LDA浅析
  13. Echarts数据图表插件--开源、大气、强大
  14. java中的执行顺序
  15. AM解调的FPGA实现
  16. 浅谈React
  17. 游戏客户端Session的统一管理
  18. Python自学:第三章 索引从0开始而不是从1
  19. xml文件以及解析
  20. [POI2012]ROZ-Fibonacci Representation (数学)

热门文章

  1. Set-----集合入门
  2. 设置myeclipse的JSP、HTML的页面编码格式
  3. [转]asp.net MVC 常见安全问题及解决方案
  4. Android popupwindow和dialog监听返回键
  5. drupal-使用hook_preprocess_field在paragraph的accordion中添加自定义数据
  6. 02--Tomcat总体结构分析一
  7. 如何用java生成随机验证码
  8. 从JavaScript的单线程执行说起
  9. ABP初始化
  10. view.getParent()与view.getRootView()