APUE学习之多线程编程(二):线程同步
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
#include <stdio.h>
#include <pthread.h> struct foo
{
int f_count;
pthread_mutex_t f_lock;
int f_id;
}; struct foo * foo_alloc(int id)
{
struct foo *fp = NULL; if ((fp = malloc(sizeof(struct foo))) != NULL)
{
fp->f_count = ;
fp->f_id = id;
if (pthread_mutex_init(&fp->f_lock, NULL) != )
{
free(fp);
return NULL;
}
} return fp;
} void foo_hold(struct foo *fp)
{
pthread_mutex_lock(&fp->f_lock);
fp->f_count++;
pthread_mutex_unlock(&fp->f_lock);
} void foo_rele(struct foo *fp)
{
pthread_mutex_lock(&fp->f_lock); if (--fp->f_count == )
{
pthread_mutex_unlock(&fp->f_lock);
pthread_mutex_destroy(&fp->f_lock);
free(fp);
}
else
{
pthread_mutex_unlock(&fp->f_lock);
}
}
#include "apue.h"
#include <pthread.h> #define NMASH 29
#define HASH(id) (((unsigned long)id) % NMASH) struct foo *fh[NMASH]; pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER; struct foo
{
int f_count;
pthread_mutex_t f_lock;
int f_id;
struct foo *f_next;
}; struct foo *foo_alloc(int id)
{
struct foo *fp = NULL;
int idx = ; if ((fp = malloc(sizeof(struct foo))) != NULL)
{
fp->f_count = ;
fp->f_id = if;
if (pthread_mutex_init(&fp->f_lock, NULL) != )
{
free(fp);
return NULL;
} idx = HASH(id);
pthread_mutex_lock(&hashlock);
fp->f_next = fh[idx];
fh[idx] = fp;
pthread_mutex_lock(&fp->f_lock);
pthread_mutex_unlock(&hashlock);
pthread_mutex_unlock(&fp->f_lock);
} return fp;
} void foo_hold(struct foo *fp)
{
pthread_mutex_lock(&fp->f_lock);
fp->f_count++;
pthread_mutex_unlock(&fp->f_lock);
} struct foo *foo_find(int id)
{
struct foo *fp = NULL; pthread_mutex_lock(&hashlock); for (fp = fh[HASH(id)]; fp != NULL; fp = fp->next)
{
if (fp->f_id = id)
{
foo_hold(fp);
break;
}
} pthread_mutex_unlock(&hashlock);
return fp;
} void foo_rele(struct foo *fp)
{
struct foo *tfp = NULL;
int idx = ; pthread_mutex_lock(&fp->f_lock); if (fp->f_count == )
{
pthread_mutex_unlock(&fp->f_lock);
pthread_mutex_lock(&hashlock);
pthread_mutex_lock(&fp->f_lock); if (fp->f_count != )
{
fp->f_count--;
pthread_mutex_unlock(&hashlock);
pthread_mutex_unlock(&fp->f_lock);
return;
} idx = HASH(fp->f_id);
tfp = fh[idx];
if (tfp = fp)
{
fh[idx] = fp->f_next
}
else
{
while(tfp->next != fp)
{
tfp = tfp->next;
}
tfp->next = fp->f_next;
} pthread_mutex_unlock(&hashlock);
pthread_mutex_unlock(&fp->f_lock);
pthread_mutex_destroy(&fp->f_lock);
free(fp);
}
else
{
fp->f_count--;
pthread_mutex_unlock(&fp->f_lock);
}
}
#include "apue.h"
#include <pthread.h> #define NMASH 29
#define HASH(id) (((unsigned long)id) % NMASH) struct foo *fh[NMASH]; pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER; struct foo
{
int f_count;
pthread_mutex_t f_lock;
int f_id;
struct foo *f_next;
}; struct foo *foo_alloc(int id)
{
struct foo *fp = NULL;
int idx = ; if ((fp = malloc(sizeof(struct foo))) != NULL)
{
fp->f_count = ;
fp->f_id = if;
if (pthread_mutex_init(&fp->f_lock, NULL) != )
{
free(fp);
return NULL;
} idx = HASH(id);
pthread_mutex_lock(&hashlock);
fp->f_next = fh[idx];
fh[idx] = fp;
pthread_mutex_lock(&fp->f_lock);
pthread_mutex_unlock(&hashlock);
pthread_mutex_unlock(&fp->f_lock);
} return fp;
} void foo_hold(struct foo *fp)
{
pthread_mutex_lock(&hashlock);
fp->f_count++;
pthread_mutex_unlock(&hashlock);
} struct foo *foo_find(int id)
{
struct foo *fp = NULL; pthread_mutex_lock(&hashlock); for (fp = fh[HASH(id)]; fp != NULL; fp = fp->next)
{
if (fp->f_id = id)
{
foo_hold(fp);
break;
}
} pthread_mutex_unlock(&hashlock);
return fp;
} void foo_rele(struct foo *fp)
{
struct foo *tfp = NULL;
int idx = ; pthread_mutex_lock(&hashlock); if (fp->f_count == )
{ idx = HASH(fp->f_id);
tfp = fh[idx];
if (tfp = fp)
{
fh[idx] = fp->f_next
}
else
{
while(tfp->next != fp)
{
tfp = tfp->next;
}
tfp->next = fp->f_next;
} pthread_mutex_unlock(&hashlock);
pthread_mutex_destroy(&fp->f_lock);
free(fp);
}
else
{
fp->f_count--;
pthread_mutex_unlock(&hashlock);
}
}
#include <pthread.h>
#include <time.h>
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict tsptr);
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
#include <stdio.h>
#include <pthread.h> struct job
{
struct job *j_next;
struct job *j_prev;
pthread_t j_id;
}; struct queue
{
struct job *q_head;
struct job *q_tail;
pthread_rwlock_t q_lock;
}; int queue_init(struct queue *qp)
{
int err; qp->q_head = NULL;
qp->q_tail = NULL;
err = pthread_rwlock_init(&qb->q_lock, NULL);
if (err != )
{
return err;
} return
} void job_insert(struct queue *qp, struct job *jp)
{
pthread_rwlock_wrlock(&qb->q_lock);
jp->next = qp->head;
jp->j_prev = NULL; if (qp->q_head != NULL)
{
qp->q_head->j_prev = jp;
}
else
{
qp->tail = jp;
}
qp->head = jp;
pthread_rwlock_unlock(&qp->q_lock);
} void job_append(struct queue *qp, struct job *jp)
{
pthread_rwlock_wrlock(&qp->q_lock);
jp->j_next = NULL;
jp->j_prev = qp->tail;
if (qp->q_tail != NULL)
{
qp->q_tail->j_next = jp;
}
qp->q_tail = jp;
pthread_rwlock_unlock(&qp->q_lock);
} void job_remove(struct queue *qp, struct job *jp)
{
pthread_rwlock_wrlock(&qp->q_lock);
if (jp == qp->q_head)
{
qp->q_head = jp->j_next;
if (qp->q_tail == jp)
{
qp->tail = NULL;
}
else
{
jp->next->j_prev = jp->j_prev;
}
}
else if (jp == qp->q_tail)
{
qp->q_tail = jp->j_prev;
jp->j_prev->j_next = NULL;
}
else
{
jp->j_prev->j_next = jp->j_next;
jp->j_next->j_prev = jp->j_prev;
}
pthread_rwlock_unlock(&qp->q_lock);
} struct job *job_find(struct queue *qp, pthread_t id)
{
struct job *jp; if (pthread_rwlock_rdlock(&qp->q_lock) != )
{
return NULL;
} for (jp = qb->q_head; jp != NULL; jp = jp->j_next)
{
if (pthread_equal(jp->j_id, id))
{
break;
}
}
pthread_rwlock_unlock(&qp->q_lock);
return jp;
}
#include <pthread.h>
#include <time.h>
int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict tsptr);
int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict tsptr);
#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_con_t *cond);
#include<pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex)
int pthread_cond_timedwait(pthread_cond_t *restrict cond, phtread_mutex_t *restrict mutex, const struct timespec *restrict tsptr)
#include<phtread.h>
int pthread_cond_signal(pthread_cond_t *cond)
int pthread_cond_broadcast(pthread_cond_t *cond)
#include <pthread.h> struct msg
{
struct msg *m_next;
}; struct msg *workq; pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER; void process_msg(void)
{
struct msg *mp; for(;;)
{
pthread_mutex_lock(&qlock);
while (workq == NULL)
{
pthread_cond_wait(&qready, &qlock);
} mp = workq;
workq = mp->m_next;
pthread_mutex_unlock(&qlock);
}
} void enqueue_msg(struct msg *mp)
{
pthread_mutex_lock(&qlock);
mp->m_next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
APUE学习之多线程编程(二):线程同步的更多相关文章
- .NET面试题解析(07)-多线程编程与线程同步
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等, ...
- .NET面试题解析(07)-多线程编程与线程同步 (转)
http://www.cnblogs.com/anding/p/5301754.html 系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实 ...
- Java多线程编程(4)--线程同步机制
一.锁 1.锁的概念 线程安全问题的产生是因为多个线程并发访问共享数据造成的,如果能将多个线程对共享数据的并发访问改为串行访问,即一个共享数据同一时刻只能被一个线程访问,就可以避免线程安全问题.锁 ...
- Win32多线程编程(3) — 线程同步与通信
一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用.新线程与创建它的线程在相同的进程上下文中运行.因此,新线程可以访问进程内核对象的所有句柄.进程中的所有内存以及同一个进程中其他所有线 ...
- C# 多线程编程第二步——线程同步与线程安全
上一篇博客学习了如何简单的使用多线程.其实普通的多线程确实很简单,但是一个安全的高效的多线程却不那么简单.所以很多时候不正确的使用多线程反倒会影响程序的性能. 下面先看一个例子 : class Pro ...
- 廖雪峰Java11多线程编程-2线程同步-3死锁
1.线程锁可以嵌套 在多线程编程中,要执行synchronized块: 必须首先获得指定对象的锁 Java的线程锁是可重入的锁.对同一个对象,同一个线程,可以多次获取他的锁,即同一把锁可以嵌套.如以下 ...
- iOS多线程编程:线程同步总结
1:原子操作 - OSAtomic系列函数 iOS平台下的原子操作函数都以OSAtomic开头,使用时需要包含头文件<libkern/OSBase.h>.不同线程如果通过原子操作函数对同一 ...
- APUE学习之多线程编程(三):线程属性、同步属性
一.线程属性 可以使用pthread_attr_t结构修改线程默认属性,并这些属性和创建的线程练习起来,可以使用pthread_att_init函数初始化pthread_attr_t结构,调 ...
- APUE学习之多线程编程(一):线程的创建和销毁
一.线程标识 和每个进程都有一个进程ID一样,每个线程也有一个线程ID,线程ID是以pthread_t数据类型来表示的,在Linux中,用无符号长整型表示pthread_t,Solaris ...
随机推荐
- 如何下载Github单个文件(Windows平台)
如何下载Github单个文件(Windows平台) 前提 安装Chrome 浏览器 Chrome浏览器 安装迅雷软件 安装Chrome 迅雷插件 可能商店里迅雷插件有好几种,这里使用这一种 一般使用者 ...
- salesforce 零基础学习(六十一)apex:component简单使用以及图片轮转播放的实现
有的时候,我们项目有可能有类似需求:做一个简单的图像轮转播放功能,不同的VF页面调用可以显示不同的图片以及不同的图片描述.这种情况,如果在每个页面单独处理相关的图像轮转播放则显得代码特别冗余,此种情况 ...
- OPEN CASCADE编译视频
为了帮助OPEN CASCADE新手顺利编译OPEN CASCADE源码,特录制了一个视频, 有了这个视频,OPEN CASCADE的编译再也不麻烦啦!
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(35)-文章发布系统②-构建项目
系列目录 注:阅读本文,需要阅读本系列的之前文章 代码生成器下载地址(文章开头处) 接下来我们建立数据库的表和各层的代码 我们只需要两张表,文章列表(MIS_Article)和类别表(MIS_Arti ...
- Linux同平台数据库整体物理迁移
Linux同平台数据库整体物理迁移 需求:A机器不再使用,要将A机器的Oracle迁移到B机器. 之前写过类似需求的文章:http://www.cnblogs.com/jyzhao/p/3968504 ...
- 使用localResizeIMG3+WebAPI实现手机端图片上传
前言 惯例~惯例~昨天发表的使用OWIN作为WebAPI的宿主..嗯..有很多人问..是不是缺少了什么 - - 好吧,如果你要把OWIN寄宿在其他的地方...代码如下: namespace Conso ...
- 【转】基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累 了一些开源的组件,就目前想到的先整理于此,如果再想到, ...
- C# - 多线程 之 信号系统
基础概览 多线程之信号系统命名空间 using System.Threading; 线程同步类的继承层次关系图 终止状态和非终止状态 在终止状态下,被WaitOne()阻塞的线程会逐个得到释放.如果一 ...
- 【Java每日一题】20161230
// 20161229问题解析请点击今日问题下方的"[Java每日一题]20161230"查看(问题解析在公众号首发,公众号ID:weknow619)package Dec2016 ...
- String类
字符串的功能 A:判断功能 boolean equals(Object obj)//比较对象 boolean eq ...