Unix环境多线程编程(三)

原创 2006年05月24日 13:13:00

1.1.1   信号量

使用POSIX 1003.1b信号量,有别于SystemV(ipc, semctl, semop)的信号量操作。

信号量是为线程间共享的资源计数。信号量的基础操作是:原子性的增加计数,和等待直到计数器非空并且原子性的减少计数。

1)       API

1.13 #include <semaphore.h>

信号量初始化

int sem_init(sem_t *sem, int pshared, unsigned int value);

返回: 如果成功0, 失败设置 Exxx error

 

初始化sem指针指向的信号量,此信号量的计数为value。第2个参数指明此信号量是本地本进程使用(0)还是进程间可以使用(非0)。Linux线程当前不支持进程间使用。因此如果pshared是非0,将返回ENOSYS错误。

 

 

1.14 #include <semaphore.h>

信号量等待函数。相当于P原语

int sem_wait(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

挂起调用此函数的线程直到sem指针指向的信号量不为0。此函数将原子性的减少信号量。

 

 

 

1.15 #include <semaphore.h>

sem_wait的非阻塞版

int sem_trywait(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

此函数是sem_wait的非阻塞版。如果sem指向的信号量是非0值,那么此计数将原子性的减少并且此函数立即返回0。如果信号量是0,那么sem_trywait函数立即返回错误EAGAIN

 

 

1.16 #include <semaphore.h>

信号量释放操作。相当于 原语V

int sem_post(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

原子性的增加由sem指向的信号量计数。这个函数不会被阻塞。

 

 

1.17 #include <semaphore.h>

获得信号量

int sem_getvalue(sem_t * sem, int * sval);

返回: 如果成功0, 失败设置 Exxx error

 

获得sem指向的信号量的指到sval中。

 

 

1.18 #include <semaphore.h>

信号量销毁函数

int sem_destroy(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

销毁一个信号量对象,释放他可能拥有的资源。在调用sem_destroy函数后没有线程可以再等待此信号量。在Linux线程实现中,没有资源于信号量相关联,因此sem_destroy事实上除了检查没有线程等待此信号量外什么也没作。

 

2)       Example

/* File sem.c */
#include
<pthread.h>

#include
<semaphore.h>
#include
<stdio.h>
#define MAXSTACK 100
int stack[MAXSTACK][2];
int size=0;
sem_t sem;
/*
从文件1.dat读取数据,每读一次,信号量加一*/
void ReadData1(void){
    FILE *fp =
fopen("1.dat","r");
    while(!feof(fp))
{
       
fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);
        
sem_post(&sem);
       
++size;
   
}
   
fclose(fp);
}
/*
从文件2.dat读取数据
*/
void ReadData2(void){
   
FILE *fp=fopen("2.dat","r");
    while(!feof(fp))
{
       
fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);
       
sem_post(&sem);
       
++size;
   
}
   
fclose(fp);
}
/*
阻塞等待缓冲区有数据,读取数据后,释放空间,继续等待
*/
void HandleData1(void){
   
while(1){
       
sem_wait(&sem);
       
printf("Plus:%d+%d=%d/n",stack[size][0],stack[size][1],
       
stack[size][0]+stack[size][1]);
       
--size;
   
}
}

void HandleData2(void){
   
while(1){
       
sem_wait(&sem);
       
printf("Multiply:%d*%d=%d/n",stack[size][0],stack[size][1],
       
stack[size][0]*stack[size][1]);
       
--size;
   
}
}
int main(void){
   
pthread_t t1,t2,t3,t4;
   
sem_init(&sem,0,0);
   
pthread_create(&t1,NULL,(void *)HandleData1,NULL);
   
pthread_create(&t2,NULL,(void *)HandleData2,NULL);
   
pthread_create(&t3,NULL,(void *)ReadData1,NULL);
   
pthread_create(&t4,NULL,(void *)ReadData2,NULL);
    /*
防止程序过早退出,让它在此无限期等待
*/
   
pthread_join(t1,NULL);
}

 

Unix环境高级编程学习笔记(七) 多线程

线程概述 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者。传统的Unix也支持线程的概念,但是在一个进程(proces...

《UNIX环境高级编程》多线程同步 pthread_cond_t

最近看《UNIX环境高级编程》多线程同步,看到他举例说条件变量pthread_cond_t怎么用,愣是没有看懂,只好在网上找了份代码,跑了跑,才弄明白 [cpp] view plaincopy 1...
  • sanjiva
  • sanjiva
  • 2015年04月15日 16:46
  • 292

UNIX环境高级编程之----多线程技术(1)

进程是系统中程序执行和资源分配的基本单位。每个进程都有自己的数据段,代码段和堆栈段,这就导致了进程在进行切换等操作起到了现场保护作用。但是为了进一步减少处理机的空转时间支持多处理器和减少上下文切换开销...

Unix环境高级编程--多线程(一)

对于刚开始写程序或者在很长一段时间,在编写程序时,我们都只会在一个main函数中进行程序的逻辑执行顺序的编写。在接触GUI程序的设计的时候,很多时候希望有一个前端显示以及后台计算的需求。此时如果以多进...

多线程 一个mutex互斥量实例(unix环境高级编程)

/* * mutex.c * * Created on: 2011-11-23 * Author: lc */ #include #include #include #i...

UNIX环境高级编程之----多线程技术(2)

创建线程实际上就是确定调用该线程函数的入口点,这里通常使用的函数是pthread_create。在线程创建之后,就开始运行相关的线程函数。在该函数运行结束,线程也会随着退出。这是其中退出线程的一种方法...

Unix环境高级编程学习笔记(七) 多线程

线程概述 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者。传统的Unix也支持线程的概念,但是在一个进程(proces...

UNIX多线程编程

  • 2011年12月11日 12:25
  • 10KB
  • 下载

UNIX环境高级编程(三)—— 静态链接库与动态链接库

0. .a/.o/.so .o 就相当于 windows 里的 obj 文件 ,一个 .c 或 .cpp 文件对应一个 .o 文件 .a 是多个 .o 合在一起,用于静态连接 ,即STATIC mod...

UNIX环境高级编程——线程

UNIX环境高级编程——线程   线程包含了表示进程内执行环境必需的信息,其中包括进程中标示线程的线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno变量以及线程私有数据。 进程的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unix环境多线程编程(三)
举报原因:
原因补充:

(最多只允许输入30个字)