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 ...
随机推荐
- Linux下常见的IO模型
前言 阻塞IO(blocking IO) 非阻塞IO(nonblocking IO) IO复用(IO multiplexing) 异步IO(asynchronous IO (the POSIX aio ...
- PostCSS深入学习: PostCSS和Sass、Stylus或LESS一起使用
如果你喜欢使用PostCSS,但又不想抛弃你最喜欢的预处理器.不用担心,你不需要作出二选一的选择,你可以把PostCSS和预处理器(Sass.Stylus或LESS)结合起来使用. 有几个PostCS ...
- Python标准模块--multiprocessing
1 模块简介 multiprocessing模块在Python2.6中引入.最初的multiprocessing是由Jesse Noller和Richard Oudkerk在PEP 371中定义.就像 ...
- spring boot(四):thymeleaf使用详解
在上篇文章springboot(二):web综合开发中简单介绍了一下thymeleaf,这篇文章将更加全面详细的介绍thymeleaf的使用.thymeleaf 是新一代的模板引擎,在spring4. ...
- js的OOP继承实现
以下视频截图均来自慕课网javascript深入浅出: 这里Student.prototype之所以使用create方法来创建,而不是直接赋Person.prototype的值,是因为如果使用赋值的话 ...
- 【Android】开发中个人遇到和使用过的值得分享的资源合集
Android-Classical-OpenSource Android开发中 个人遇到和使用过的值得分享的资源合集 Trinea的OpenProject 强烈推荐的Android 开源项目分类汇总, ...
- ASP.NET Core 中文文档 第二章 指南(4.7)添加搜索
原文:Adding Search 作者:Rick Anderson 翻译:魏美娟(初见) 校对:谢炀(Kiler) .孟帅洋(书缘).张仁建(第二年.夏) 在本节中,你可以为 Index 方法添加查询 ...
- go语言结构体
定义: 是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体. 成员: 每个值称为结构体的成员. 示例: 用结构体的经典案例处理公司的员工信息,每个员工信息包含一个唯一的员工编号.员工的名字. ...
- 导出BOM表
1.Report->Bill of Materials for Project 将Value拖上左上角的Grouped Columns 2.在Excel表中全选器件,右键设置"设置单元 ...
- C#基础知识六之委托(delegate、Action、Func、predicate)
1. 什么是委托 官方解释 委托是定义方法签名的类型,当实例化委托时,您可以将其实例化与任何具有兼容签名的方法想关联,可以通过委托实例调用方法. 个人理解 委托通俗一点说就是把一件事情交给别人来帮助完 ...