直接使用一个共享变量,来是两个线程之间进行切换是非常笨拙而且没有效率的;
信号量--
互斥量--
这两者是相互通过对方来实现的;
比如,如果想控制某一时刻只有一个线程可以访问一些共享内存,使用互斥量要自然一些;
但是控制一组相同的对下的访问时,比如同5条可用的电话线中分配1条给某个可用的线程,那么使用计数信号量;
------------------------------------- 信号量,是一个特殊类型的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作,及时一个多线程程序也是如比;
意味着如果两个(更多)的现场试图改变一个信号量的值,系统保证所有的操作都将一次进行
信号量,二进制信号量只有0/1两种取值,还有一种更通用的信号量--计数信号量;
信号量函数的名字以sem_开头,而不像大多数线程函数那样以pthread_开头
基本信号量函数有四个:
---
#include<semaphore.h>
int sem_init(sem_t *sem,int psthared, unsigned int value);
信号量通过这个函数来创建,由sem指向的信号量对象,设置他的共享参数,给一个初始的整数值
psthared,控制信号量的类型,其值为0,表示这个信号量是当前进程的局部信号量,否则该信号量可以在多个进程见共享
---
#include <semaphore.h>
int sem_wait(sem_t *sem);
wait函数将信号量的减到1,但是会等到新好两有个非零值才会开始减法操作;
如果对为0的信号量调用sem_wait函数,函数会等待,知道其他线程增加了该信号量的值使其!=0; ---
#include <semaphore.h>
int sem_post(sem_t *sem);
post函数作用是以原子操作的方式将信号量的值+1;
描述:”在单个函数中就能原子化地进行测试和设置“的能力很有价值;
---
sem_trywait()是sem_wait的非阻塞版本
以一个信号量指针为参数,清理该信号量拥有的所有资源,如果企图清理信号量正被一个线程等待,返回一个错误
---
#include <semaphore.h>
int sem_destroy(sem_t *sem); ==============
例子;
/*************************************************************************
> File Name: thread3.c
> Author:
> Mail:
> Created Time: 2016年03月27日 星期日 10时01分36秒
************************************************************************/ #include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<semaphore.h> void *thread_function(void *arg);
sem_t bin_sem; #define WORK_SIZE 1024
char work_area[WORK_SIZE]; int main(){
int res;
pthread_t a_thread;
void *thread_result; res = sem_init(&bin_sem,,);
if(res != ){
perror("semaphore initialization failed");
exit(EXIT_FAILURE);
} res = pthread_create(&a_thread,NULL,thread_function,NULL);
if(res!=){
perror("thread creation failed");
exit(EXIT_FAILURE);
}else{
printf("thread creation successful\n");
} printf("input some text, Enter 'end' to finish\n");
while(strncmp("end",work_area,) != ){
fgets(work_area,WORK_SIZE,stdin);
int res = sem_post(&bin_sem);
if(res != ){
printf("sem_post failed\n");
exit(EXIT_FAILURE);
}else{
printf("sem_post seccussful,bin_sem = \n");
}
} printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if(res!=){
perror("thread join failed");
exit(EXIT_FAILURE);
} printf("thread joined\n");
sem_destroy(&bin_sem);
exit(EXIT_SUCCESS);
} void *thread_function(void *arg){
printf("begin thread_function\n");
int w = sem_wait(&bin_sem);
if(w != ){
printf("sem_wait_1 failed\n");
exit(EXIT_FAILURE);
}else{
printf("sem_wait_1 seccussful\n");
} while(strncmp("end",work_area,) != ){
printf("you input %d characters\n",strlen(work_area)-);
sem_wait(&bin_sem);
}
printf("----\n");
pthread_exit(NULL);
}

编译方法:

lizhen@lizhen:~/basic$ cc -D_REENTANT thread3.c -o thread3 -lpthread
thread3.c: In function ‘thread_function’:
thread3.c::: warning: format ‘%d’ expects argument of type ‘int’, but argument has type ‘size_t’ [-Wformat=]
printf("you input %d characters\n",strlen(work_area)-);
^
lizhen@lizhen:~/basic$

运行情况:

[code=c]
lizhen@lizhen:~/basic$ ./thread3
thread creation successful
input some text, Enter 'end' to finish
begin thread_function
kl
sem_post seccussful,bin_sem =
sem_wait_1 seccussful
you input characters
end
sem_post seccussful,bin_sem =
----

代码分析:

为什么不能看到thread_function 线程函数返回,接着执行main()主线程的结尾部分;而是好像一直等待什么??
这是一个信号量同步的问题,
main()接受输入,
当输入的字符串不是“end”时,thread_function()计算字符串的长度并输出
,利用信号量bin_sem来控制main()与thread_function()的执行;
=====================
结论,我自己找到问题所在了,
因为在main()中,while判断中,strcmp(“end”,“work_area”,) != 中,
work_area不应该加双引号的,
main()中,while()循环会一直执行下去,接受fgets()输入,sem_post(&bin_sem);
thread_function()线程中的while开始执行,当work_area不是“end”时打印字符串的长度;当work_area是“end”的时候跳出while()循环,执行pthread_exit(NULL);线程结束
但是main中的while()会一直循环下去的,因为它的判断条件一直“为真”,会一直等待输入,对信号量执行sem_post(&bin_sem);

[linux basic 基础]----同步信号量的更多相关文章

  1. [linux basic 基础]----同步互斥量

    互斥量,运行程序元锁住某个对象,使得每次只能有一个线程访问它:为了控制对关键代码的访问,必须在进入这段代码之前锁住一个互斥量,然后在完成操作之后解锁它 :基本函数与用于信号量的函数非常相似#inclu ...

  2. [linux basic 基础]----线程的属性

    在信号量和互斥量例子中,我们都是在程序推出之前利用pthread_join对线程进行再次同步:如果想让thread想创建它的线程返回数据我需要这么做:问题:我们有时候既不需要第二个线程向main线程返 ...

  3. [linux basic基础]----套接字

    套接字是一种通信机制,凭借这种机制client/server系统的开发者既可以在本地机器上进行,也可以跨网络进行. 1,服务器应用程序用系统调用socket来创建一个套接字,他是系统分配给服务器进程的 ...

  4. [linux basic]基础--信号

    线程->信号信号,是unix和linux系统响应某些条件而产生的一个事件.接收到该信号的进程会相应地采取一些行动.raise生成表示一个信号的产生catch捕获表示接受到一个信号的产生:信号是由 ...

  5. linux系统编程:线程同步-信号量(semaphore)

    线程同步-信号量(semaphore) 生产者与消费者问题再思考 在实际生活中,仅仅要有商品.消费者就能够消费,这没问题. 但生产者的生产并非无限的.比如,仓库是有限的,原材料是有限的,生产指标受消费 ...

  6. Linux的原子操作与同步机制

    Linux的原子操作与同步机制   .进程1执行完“mov eax, [count]”后,寄存器eax内保存了count的值0.此时,进程2被调度执行,抢占了进程1的CPU的控制权.进程2执行“cou ...

  7. linux系统基础(一)

    Linux简介与安装Unix ;windows; linux; apple(mac) linux=kernel (内核)=OSlinux全是文件============================ ...

  8. linux编程基础汇总贴

    linux编程基础汇总贴http://newzol.cn/forum.php?mod=viewthread&tid=67&fromuid=3(出处: newzol) 1.管道 http ...

  9. Linux的基础命令, django的安装与使用

    一. Linux一些基础指令 cat命令, 用于查看纯文本文件(常用于内容较少的) cat 校花的故事.txt # 查看文件 cat -n 校花的故事.txt # 查看文件并显示行号 -n 显示行号 ...

随机推荐

  1. 快速对字符转义,避免跨站攻击XSS

    XSS已经成为非常流行的网站攻击方式,为了安全起见,尽量避免用户的输入.可是有些情况下不仅不避免,反而要求鼓励输入,比如写博客.博客园开放性很高,可以运行手写的JS.之前比较著名的例子就是,凡是看到某 ...

  2. POJ 1797 Heavy Transportation

    题目链接:http://poj.org/problem?id=1797 Heavy Transportation Time Limit: 3000MS   Memory Limit: 30000K T ...

  3. C++ Primer : 第十二章 : 动态内存之动态数组

    动态数组的分配和释放 new和数组 C++语言和标准库提供了一次分配一个对象数组的方法,定义了另一种new表达式语法.我们需要在类型名后跟一对方括号,在其中指明要分配的对象的数目. int* arr ...

  4. spring mvc显示图片(个人记录)

    @ResponseBody @RequestMapping(value = {"/",""}, method = RequestMethod.GET, prod ...

  5. 1-3-1 关于API

    主要内容:API函数及其相关内容的介绍.Windows编程相关基础知识介绍 1.API函数的概念 <1>API(Application Programming interface),即应用 ...

  6. VC线程中操作控件,引起程序卡死的问题。

    [问题还原] 线程中操作控件,具体为控制一个按键的使能,使能后结束线程. 主程序中有一个死循环,等待线程结束. 然后,就没有然后了-- [解决方案] 在主程序死循环中,如果检测到界面消息,优先处理掉.

  7. kuangbin_UnionFind B (POJ 1611)

    过程是模板 merge完后扫一下几个跟0同祖先节点就是答案了 #include <iostream> #include <string> #include <cstdio ...

  8. spring beans源码解读之--Bean的定义及包装

    bean的定义,包装是java bean的基础.再怎么强调它的重要性都不为过,因此深入 了解这块的代码对以后的代码研究可以起到事半功倍的功效. 1. Bean的定义BeanDefinition 1.1 ...

  9. C++的异常处理

    一.什么是异常处理 一句话:异常处理就是处理程序中的错误. 二.为什么需要异常处理,以及异常处理的基本思想 C++之父Bjarne Stroustrup在<The C++ Programming ...

  10. JSBinding / Gen Bindings

    Classes in JSBindingSettings.classes array will be exported to JavaScript. There are already many cl ...