linux信号同步,[linux basic 基础]----同步信号量

直接使用一个共享变量,来是两个线程之间进行切换是非常笨拙而且没有效率的;

信号量--

互斥量--

这两者是相互通过对方来实现的;

比如,如果想控制某一时刻只有一个线程可以访问一些共享内存,使用互斥量要自然一些;

但是控制一组相同的对下的访问时,比如同5条可用的电话线中分配1条给某个可用的线程,那么使用计数信号量;

-------------------------------------

信号量,是一个特殊类型的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作,及时一个多线程程序也是如比;

意味着如果两个(更多)的现场试图改变一个信号量的值,系统保证所有的操作都将一次进行

信号量,二进制信号量只有0/1两种取值,还有一种更通用的信号量--计数信号量;

信号量函数的名字以sem_开头,而不像大多数线程函数那样以pthread_开头

基本信号量函数有四个:

---

#include

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

信号量通过这个函数来创建,由sem指向的信号量对象,设置他的共享参数,给一个初始的整数值

psthared,控制信号量的类型,其值为0,表示这个信号量是当前进程的局部信号量,否则该信号量可以在多个进程见共享

---

#include

int sem_wait(sem_t *sem);

wait函数将信号量的减到1,但是会等到新好两有个非零值才会开始减法操作;

如果对为0的信号量调用sem_wait函数,函数会等待,知道其他线程增加了该信号量的值使其!=0;

---

#include

int sem_post(sem_t *sem);

post函数作用是以原子操作的方式将信号量的值+1;

描述:”在单个函数中就能原子化地进行测试和设置“的能力很有价值;

---

sem_trywait()是sem_wait的非阻塞版本

以一个信号量指针为参数,清理该信号量拥有的所有资源,如果企图清理信号量正被一个线程等待,返回一个错误

---

#include

int sem_destroy(sem_t *sem);

==============

例子;

/*************************************************************************

> File Name: thread3.c

> Author:

> Mail:

> Created Time: 2016年03月27日 星期日 10时01分36秒

************************************************************************/

#include

#include

#include

#include

#include

#include

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 基础]----同步互斥量

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

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

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

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

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

[linux basic]基础--信号

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

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

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

Linux的原子操作与同步机制

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

linux系统基础(一)

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

linux编程基础汇总贴

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

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

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

随机推荐

WebView一般用法总结

下面是webview常规的用法: import android.annotation.SuppressLint;import android.app.Activity;import android.o ...

兼容Android的水波纹效果

Android的水波纹效果只有高版本才有,我们希望自己的应用在低版本用低版本的阴影,高版本用水波纹,这怎么做呢?其实,只要分drawable和drawablev21两个文件夹就好了. 普通情况下的se ...

FragmentHelper

package com.icitymobile.anda.util; import java.lang.ref.SoftReference; import java.util.ArrayList; i ...

CSS flex让所有灵活的项目都带有相同的长度,忽略它们的内容:

.flexbox {     display: -webkit-box;     display: -webkit-flex;     display: -ms-flexbox;     displa ...

正式学习React(四) 前序篇

预热 redux 函数内部包含了大量柯里化函数以及代码组合思想 柯里化函数(curry) 通俗的来讲,可以用一句话概括柯里化函数:返回函数的函数 // example const funcA = (a ...

7.28.1 Spring构造注入还是设置注入

1. 构造方法注入代码如下:public UserManagerImpl(UserDao userDao) {                                              ...

Python开发——数据类型【字符串格式化】

字符串格式化之——% # 字符串格式化 msg = 'I am %s , My hobby is %s'%('yuan','play') print(msg) # I am yuan , My hob ...

day13: 迭代器和生成器

1,思考所有可以被for循环的:list,tuple,set,dict,range,enumerate,f,str,差不多了,为何这些数据类型可以被for循环呢? 2,一个标准的装饰器函数 from ...

[转]浅谈Android五大布局(二)——RelativeLayout和TableLayout

在浅谈Android五大布局(一)中已经描述了LinearLayout(线性布局).FrameLayout(单帧布局)和AbsoulteLayout(绝对布局)三种布局结构,剩下的两种布局Relati ...

HTTP 随笔

浏览器发送HTTP请求主要分为三部分请求行,Response Headers(响应头信息)和Request Headers(请求头信息). 请求行有分为三部分:请求方法,请求路径和请求协议 请求方法有 ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值