信号量进行同步(linux POSIX的实时扩展,用于线程)!

信号量提出背景:

程序中2线程共享全局变量时(一个是main函数顺序“线程”,一个是create线程),会导致“忙等待”时,线程之间

来回切换,非常笨拙且没有效率,由此荷兰计算机科学家Dijkstra提出了信号量的概念;


对信号量的一般特点

1. 有2组,一组是posix的实时扩展,用于线程(本博的主要内容);另外一组为系统V信号量,用于进程同步;

2. 信号量是特殊的变量,可以被增加和减少,一般用最简单的信号量--二进制,另外一种是计数信号量,不在此讨论;

    计数信号量不常用


相关函数

线程中使用的基本信号量函数有4个,

1.头文件:#include <semaphore.h>

2.原型:

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

pshared 参数控制信号量的类型,为0,:表示这个信号量是当前的进程的局部信号量,否则,这个信号量可以在多个进程之间

共享;(该博只对不能在进程间共享的信号量感兴趣);


int sem_post(sem_t *sem);

int sem_wait(sem_t *sem);

1. sem_post 函数的作用是以原子操作的方式给信号量的值加1.(原子操作:P424有说明);

2. sem_wait函数以原子操作的方式将信号量的值减1,它会等待直到信号量有个非零值才会开始减操作,为0就等待;

3. 如果有2个wait等待信号量为非零值,只有一个等待线程开始对信号量减1,另外一个线程继续等待;


int sem_destroy(sem_t  *sem);

与大多数linux函数一样,成功返回0。


例子:

root@ubuntu:/mnt/hgfs/D/linux_program/ch12# cat -n thread3.c
     1	#include <stdio.h>
     2	#include <unistd.h>
     3	#include <stdlib.h>
     4	#include <string.h>
     5	#include <pthread.h>
     6	#include <semaphore.h>
     7	
     8	void *thread_function(void *arg);
     9	sem_t bin_sem;
    10	
    11	#define WORK_SIZE 1024
    12	char work_area[WORK_SIZE];
    13	
    14	int main() {
    15	    int res;
    16	    pthread_t a_thread;
    17	    void *thread_result;
    18	
    19	    res = sem_init(&bin_sem, 0, 0);
    20	    if (res) {
    21	        perror("Semaphore initialization failed");
    22	        exit(EXIT_FAILURE);
    23	    }
    24	    res = pthread_create(&a_thread, NULL, thread_function, NULL);
    25	    if (res) {
    26	        perror("Thread creation failed");
    27	        exit(EXIT_FAILURE);
    28	    }
    29	    printf("Input some text. Enter 'end' to finish\n");
    30	    while(memcmp("end", work_area, 3) != 0) {
    31	        fgets(work_area, WORK_SIZE, stdin);
    32	        sem_post(&bin_sem);
    33	    }
    34	    printf("\nWaiting for thread to finish...\n");
    35	    res = pthread_join(a_thread, &thread_result);
    36	    if (res) {
    37	        perror("Thread join failed");
    38	        exit(EXIT_FAILURE);
    39	    }
    40	    printf("Thread joined\n");
    41	    sem_destroy(&bin_sem);
    42	    exit(EXIT_SUCCESS);
    43	}
    44	
    45	void *thread_function(void *arg) {
    46		sem_wait(&bin_sem);
    47	    while(memcmp("end", work_area, 3) != 0) {
    48	        printf("You input %d characters\n", strlen(work_area)-1);
    49	   		sem_wait(&bin_sem);
    50		 }
    51	    pthread_exit(NULL);
    52	}
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3
Input some text. Enter 'end' to finish
end

Waiting for thread to finish...
Thread joined
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3
Input some text. Enter 'end' to finish
hello world
You input 11 characters
endget

Waiting for thread to finish...
Thread joined
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# 

去掉thread_function函数体内的第一个sem_wait(&bin_sem)会出现什么现象,删除第二个呢?初始设信号量为1又是怎么打印呢?

删除第一个的打印情况:

root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3
Input some text. Enter 'end' to finish
You input -1 characters
clear
You input 5 characters
end

Waiting for thread to finish...
Thread joined
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# 

删除第二个sem_wait(&bin_sem)打印情况如下:(死循环)

root@ubuntu:/mnt/hgfs/D/linux_program/ch12# gcc -D_REENTRANT -o thread3 thread3.c -lpthread
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3
Input some text. Enter 'end' to finish
hello csdn
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
^[^AYou input 10 characters
You input 10 characters
You input 10 characters
You input 10 characters
^C
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# 

初始设信号量为1又是怎么打印:

root@ubuntu:/mnt/hgfs/D/linux_program/ch12# ./thread3
Input some text. Enter 'end' to finish
You input -1 characters
clear
You input 5 characters
c
You input 1 characters
hello csdn
You input 10 characters
end

Waiting for thread to finish...
Thread joined
root@ubuntu:/mnt/hgfs/D/linux_program/ch12# 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值