- 浏览: 238867 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
zhangzijun1984:
谢谢! 写的很详细
ruby 的数组操作 -
jcdby:
非常棒的文章。我从头看到了尾。但是为什么最后的关键部分不完整呢 ...
javascript 函数对象 -
56553655:
giianhui 写道希望能介绍一下这个类的使用场景,谢谢!看 ...
sun.misc.Unsafe 的使用 -
liuInsect:
为什么 这样就可以访问了呢? 是改变了什么设置吗??? sec ...
sun.misc.Unsafe 的使用 -
softor:
set什么啊?
MySQL 的 source 命令处理中文问题
msgdequeue.h
本例示范Linux信号量的基本用法。
该范例使用了两个线程分别对一个公用队列进行入队和出队操作,
并用信号量进行控制,当队列空时出队操作可以被阻塞,
当队列满时入队操作可以被阻塞。
主要用到的信号量函数有:
sem_init:初始化信号量sem_t,初始化的时候可以指定信号量的初始值,以及是否可以在多进程间共享。
sem_wait:一直阻塞等待直到信号量>0。
sem_timedwait:阻塞等待若干时间直到信号量>0。
sem_post:使信号量加1。
sem_destroy:释放信号量。和sem_init对应。
关于各函数的具体参数请用man查看。如man sem_init可查看该函数的帮助。
下面看具体的代码:
//--------------------------msgdequeue.h开始-------------------------------------
//实现可控队列
#ifndef MSGDEQUEUE_H
#define MSGDEQUEUE_H
#include "tmutex.h"
#include <iostream>
#include <errno.h>
#include <time.h>
#include <semaphore.h>
#include <deque>
using namespace std;
template<typename T,typename MUTEX_TYPE = ThreadMutex>
class CMessageDequeue
{
public:
CMessageDequeue(size_t MaxSize) : m_MaxSize( MaxSize ){
sem_init( &m_enques,0, m_MaxSize ); //入队信号量初始化为MaxSize,最多可容纳MaxSize各元素
sem_init( &m_deques,0,0 ); //队列刚开始为空,出队信号量初始为0
}
~CMessageDequeue(){
sem_destroy(&m_enques);
sem_destroy(&m_deques);
}
int sem_wait_i( sem_t *psem, int mswait ){
//等待信号量变成>0,mswait为等待时间,若mswait<0则无穷等待,否则等待若干mswait毫秒。
if( mswait < 0 ){
int rv = 0;
while( ((rv = sem_wait(psem) ) != 0 ) && (errno == EINTR ) ); //等待信号量,errno==EINTR屏蔽其他信号事件引起的等待中断
return rv;
}else{
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts ); //获取当前时间
ts.tv_sec += (mswait / 1000 ); //加上等待时间的秒数
ts.tv_nsec += ( mswait % 1000 ) * 1000; //加上等待时间纳秒数
int rv = 0;
while( ((rv=sem_timedwait( psem, &ts ))!=0) && (errno == EINTR) ); //等待信号量,errno==EINTR屏蔽其他信号事件引起的等待中断
return rv;
}
}
bool push_back( const T &item, int mswait = -1 ){
//等待mswait毫秒直到将item插入队列,mswait为-1则一直等待
if( -1 == sem_wait_i( &m_enques, mswait )){
return false;
}
//AUTO_GUARD:定界加锁,见Linux多线程及临界区编程例解的tmutex.h文件定义。
AUTO_GUARD( g, MUTEX_TYPE, m_lock );
try{
m_data.push_back( item );
cout << "push " << item << endl;
sem_post( &m_deques );
return true;
}catch(){
return false;
}
}
bool pop_front( T &item, bool bpop = true, int mswait = -1 ){
//等待mswait毫秒直到从队列取出元素,mswait为-1则一直等待
if( -1 == sem_wait_i( &m_deques, mswait ) ){
return false;
}
//AUTO_GUARD:定界加锁,见Linux多线程及临界区编程例解的tmutex.h文件定义。
AUTO_GUARD( g, MUTEX_TYPE, m_lock );
try{
item = m_data.front();
if( bpop ){
m_data.pop_front();
cout << "pop " << item << endl;
}
sem_post( &m_enques );
return true;
}catch(){
return false;
}
}
inline size_t size(){
return m_data.size();
}
private:
MUTEX_TYPE m_lock;
deque<T> m_data;
size_t m_MaxSize;
sem_t m_enques;
sem_t m_deques;
};
#endif
#include "msgdequeue.h"
#include <pthread.h>
#include <iostream>
using namespace std;
CMessageDequeue<int> qq(5);
void *get_thread(void *parg);
void *put_thread(void *parg);
void *get_thread(void *parg){
while(true){
int a = -1;
if( !qq.pop_front( a,true, 1000 ) ){
cout << "pop failed. size=" << qq.size() <<endl;
}
}
return NULL;
}
void *put_thread(void *parg){
for(int i=1; i<=30; i++){
qq.push_back( i, -1 );
}
return NULL;
}
int main()
{
pthread_t pget,pput;
pthread_create( &pget,NULL,get_thread,NULL);
pthread_create( &pput, NULL, put_thread,NULL);
pthread_join( pget,NULL ); pthread_join( pput,NULL );
return 0;
}
tmutex.h
#ifndef TMUTEX_H
#define TMUTEX_H
#include <pthread.h>
//线程互斥量
struct ThreadMutex
{
ThreadMutex()
{
pthread_mutex_init(&mtx,NULL);
}
~ThreadMutex()
{
pthread_mutex_destroy( &mtx );
}
inline void lock()
{
pthread_mutex_lock( &mtx );
}
inline void unlock()
{
pthread_mutex_unlock( &mtx );
}
pthread_mutex_t mtx;
};
//空互斥量,即调用lock时什么事都不做。
struct NullMutex
{
inline void lock()
{
}
inline void unlock()
{
}
};
template<class T>
class CAutoGuard
{
public:
CAutoGuard(T &mtx) : m_mtx(mtx)
{
m_mtx.lock();
}
~CAutoGuard()
{
m_mtx.unlock();
}
protected:
T &m_mtx;
};
#define AUTO_GUARD( guard_tmp_var, MUTEX_TYPE, mtx )
CAutoGuard<MUTEX_TYPE> guard_tmp_var(mtx)
#endif
发表评论
-
c 编译时与 c++的区别
2013-05-24 16:48 0int main() {print();aa(2);} 在 ... -
stack溢出 ** stack smashing detected ***: ./a.out terminated
2013-05-10 13:08 6144该类错误是修改了返回 ... -
栈内分配大内存会导致 段错误
2013-03-14 10:24 0int main() { double a[100000000 ... -
extern "C" 的使用
2013-03-06 14:04 0extern "C" 包含双重含义,从字 ... -
error C2504 继承时 undefined 基类
2012-12-24 13:41 0之前写程序时,最喜欢把类的头文件全部放到stdafx.h ... -
c++ attribute
2012-11-14 14:38 0插件机制 http://yaronspace.cn/blog ... -
svm核心算法
2012-09-27 17:06 0http://blog.csdn.net/zhuyue3938 ... -
跳跃表
2012-08-02 11:36 0http://imtinx.iteye.com/blog/12 ... -
指针与数组在结构体中的差别
2012-01-19 13:49 1209在结构体中,数组和指针最大的的区别为: 数组将信息 ... -
initrd
2011-08-19 18:01 0ubuntu mkinitramfs -o yourinit ... -
calloc 和 malloc
2011-07-28 14:08 971aa malloc 和 calloc malloc 函数原型 ... -
指针符号--误解
2011-07-27 17:17 912一、指向函数的指针和返回值为指针的函数 指向函数的指针和返回值 ... -
c语言0值标志
2011-07-27 07:15 13430 NUll \0 NUL EOF 0 :整数0 NULL ... -
c语言编译问题
2011-07-12 19:09 0c编译是若遇上类似如下问题, heap.c:(.text+0x ... -
静态链接库和动态链接库
2011-05-26 18:24 1064http://blog.csdn.net/fengyv/arc ... -
c/c++中 static 作用 和 c/c++中存储区域
2011-05-10 08:33 1697static有两种用法:面向过程程序设计中的static和面向 ... -
c++ 的四种显示数据类型转换
2011-04-26 15:35 1794C++提供了四种新的类型强制: static_cast co ... -
gcc,g++ 编译的区别
2011-03-09 14:15 1432test.cpp int main() { return 1; ... -
window gcc 编译工具--DJGPP
2011-02-17 15:06 1413http://www.delorie.com/djgpp/zi ... -
处理器架构
2011-01-17 10:17 08.现代微机结构_Pentium_and_core2
相关推荐
本资源“Sem.rar”包含的是一个关于System V信号量的C语言实现,特别适用于Linux环境。System V信号量是一种同步原语,用于解决多进程间的资源访问冲突问题,确保共享数据的安全性。 首先,让我们深入理解什么是...
例如,POSIX标准提供了一套信号量API,包括`sem_init()`、`sem_wait()`、`sem_post()`等函数。 #### 三、信号量的实现 在给定的部分内容中,提供了两个示例程序:`sema.c`和`semb.c`,它们共同演示了信号量的使用...
1. **sem_init(sem_t\* sem, int pshared, unsigned value)**:初始化信号量,参数`sem`指向待初始化的信号量对象,`value`为其初始值,`pshared`指示信号量是否可以在进程间共享。 2. **sem_destroy(sem_t\* sem)*...
在Linux中,有名信号量可以通过`sem_open()`, `sem_post()`, `sem_wait()`, `sem_close()`和`sem_unlink()`等系统调用来操作。 1. **创建有名信号量**: 使用`sem_open()`函数创建有名信号量。该函数需要一个唯一...
### uC/OS-III信号量详解 #### 一、信号量概述 信号量作为一种重要的同步机制,在嵌入式实时操作系统中发挥着关键作用。它主要用于处理任务间通信及资源的互斥访问问题。uC/OS-III作为一款广泛使用的嵌入式实时...
在"sem.rar"这个压缩包中,可能包含的是关于t-engine系统中信号量编程的示例代码或教程。"www.pudn.com.txt"可能是相关资料的来源链接或说明,供进一步学习和参考。通过这些资源,开发者可以深入理解如何在实际项目...
为了避免这种情况,可以调整信号量属性,如使用`SEM_Q_PRIORITY`,并确保在创建时将信号量设置为满状态(SEM_FULL)。 使用信号量时应注意以下几点: 1. 不同用途的信号量应配置不同的属性和初始值。 2. 在互斥访问...
"sem.tar.gz_linux 信号量_linux 封装"是一个压缩包,它包含了一个已经封装好的信号量接口,便于开发者在自己的程序中方便地使用信号量进行进程间的通信和同步。 信号量的基本概念是源自于荷兰计算机科学家Dijkstra...
无名信号量的创建通常使用`sem_init()`函数,该函数接收三个参数:指向信号量结构体的指针、标志(决定信号量是否是进程间共享)和初始值。例如: ```c #include sem_t sem; sem_init(&sem, 0, 1); // 初始化一个...
例如,在上面的代码中,我们创建了一个信号量集`Sem_F`,并将其用于控制三个任务之间的同步。任务`MyTask`只有在任务`YouTask`和`HerTask`都发送了信号以后才能运行。 信号量集的优点 信号量集有一些优点,例如: ...
其中,`sem_init()`函数的第一个参数是指向信号量的指针,第二个参数为0表示无名信号量,第三个参数初始化信号量的值。 ##### 2. 有名信号量 有名信号量用于进程间通信,其值保存在文件系统中,因此可以在不同进程...
- `sem_init()`: 初始化信号量,传入信号量指针、初始值和是否为共享信号量标志。 - `sem_wait()`: 也称为P操作,减小信号量的值,如果值小于0,则线程被阻塞。 - `sem_post()`: 也称为V操作,增加信号量的值,若...
`rt_sem_init()`函数用于初始化一个静态信号量,它需要三个参数:信号量结构体指针、信号量名称和初始值。例如,我们可以创建一个初始值为1的二进制信号量,这样只有一个线程能获得该信号量并访问资源。 ```c rt_...
`sem_init()`、`sem_post()`、`sem_wait()`、`sem_trywait()`和`sem_destroy()`是其核心函数,它们共同维护了信号量的创建、修改、检查和销毁,从而确保并发环境下的数据一致性。在实际编程中,信号量是一种强大且...
在实际编程中,我们可以使用系统提供的API来操作信号量,例如在Unix/Linux系统中,可以使用`sem_init()`、`sem_wait()`(P操作)和`sem_post()`(V操作)等函数。 在多线程环境下,信号量常用于控制对共享资源的...
在这个实验中,学生需要编写`sem.c`文件,这通常是实现信号量操作的核心部分。可能包括对信号量的初始化、P操作和V操作的实现。例如,可以使用互斥锁(mutex)来实现二进制信号量,或者使用条件变量(condition ...
在上述代码中,`N_SEM`宏定义了使用哪种类型的信号量,当其值为0时使用匿名信号量,非0则使用有名信号量。 在创建有名信号量时,我们使用`sem_open`函数,提供信号量的路径名`SEM_PATH`和相应的权限。而匿名信号量...
2. 计数信号量:可以控制同时访问资源的线程数量,`sem_t`类型也可以表示计数信号量。 信号量的操作函数包括: - 初始化:`sem_init()`用于初始化信号量。 - P操作(获取):`sem_wait()`或`sem_p()`,若信号量值...
在C语言中,信号量通常通过系统调用来实现,如`sem_open`, `sem_post`, `sem_wait`等。`semaphore.c`很可能是这个示例的主要源代码文件,它将演示如何在程序中创建、初始化、增加和减少信号量。`semaphore.h`可能...