Linux IPC 进程间通信——信号量sem

       

目录

函数接口

示例一:用一个信号量实现互斥访问

运行效果:

示例二:用连个信号量实现有序访问

运行效果:


 信号量有区别于管道、消息队列等IPC,它主要是通过访问一个计数器,通过判断它的值来决定是否可以访问一个公共资源(可以是全局变量、文件等)。

函数接口

定义:sem_t sem;
始化信号量:sem_init (sem_t *sem, int pshared, unsigned int value);
pshared为0表同一个进程的不同线程之间共享,这个sem值必须是线程可见的位置;如果非0,表示不同进程之间共享,它必须存在所有共享进程可以见的位置如共享内存;
value是sem的初始化值
头文件#include
链接库:pthread


P操作:sem_wait(sem_t *sem);
判断信号量是否大于0,如果大于0,执行减一操作,并继续sem_wait之后的代码;如果当前sem等于0,阻塞等待直至大于零(大于零之后执行减一操作,继续sem_wait之后的代码)。如果深入看sem_wait的实现,它是sem_timedwait (sem_t *sem, const struct timespec *abstime)的实现,只不过这里指定的abstime为0;当然也可以用sem_timedwait指定时间来实现非阻塞操作。


V操作:sem_post(sem_t *sem);
信号量值加一,直接返回;

示例一:用一个信号量实现互斥访问


#include 
#include 
#include 
#include 
 
sem_t g_sem;   //定义两个信号量
char ch = 'A';
char Max = 'a' ;


void *pthread_g(void *arg)  
{
    while(ch < Max)
    {
        sem_wait(&g_sem);
        printf("%s get source [%c]\n", __func__, ch);
        
        sem_post(&g_sem);
        sleep(1);
    }

    return 0;
}
 
void *pthread_p(void *arg)  
{

    while(ch < Max)
    {
        sem_wait(&g_sem);
        ch++;
        printf("%s get source [%c]\n", __func__, ch);
        
        sem_post(&g_sem);
        sleep(1);
    }

    return 0;
}
 
int main(int argc, char *argv[])
{
    pthread_t tid1,tid2;
    sem_init(&g_sem, 0, 1); // 同一进程的不同线程的sem,初始化信号量为1
    
    // 创建两个线程
    pthread_create(&tid1, NULL, pthread_g, NULL);
    pthread_create(&tid2, NULL, pthread_p, NULL);
    
    // 回收线程
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    
    return 0;
}

运行效果:

pthread_p get source [B]
pthread_g get source [B]
pthread_p get source [C]
pthread_g get source [C]
pthread_p get source [D]
pthread_g get source [D]
pthread_p get source [E]
pthread_g get source [E]
pthread_p get source [F]
pthread_g get source [F]
pthread_p get source [G]
pthread_g get source [G]
pthread_p get source [H]
pthread_g get source [H]
pthread_p get source [I]
pthread_g get source [I]
pthread_g get source [I]
pthread_p get source [J]
pthread_g get source [J]
pthread_p get source [K]
pthread_g get source [K]
pthread_p get source [L]
pthread_g get source [L]
pthread_p get source [M]
pthread_g get source [M]
pthread_p get source [N]
pthread_g get source [N]
pthread_p get source [O]
pthread_g get source [O]
pthread_p get source [P]
pthread_g get source [P]
pthread_p get source [Q]
pthread_g get source [Q]
pthread_p get source [R]
pthread_g get source [R]
pthread_p get source [S]
pthread_g get source [S]
pthread_p get source [T]
pthread_g get source [T]
pthread_p get source [U]
pthread_g get source [U]
pthread_p get source [V]
pthread_g get source [V]
pthread_p get source [W]
pthread_g get source [W]
pthread_p get source [X]
pthread_g get source [X]
pthread_p get source [Y]
pthread_g get source [Y]
pthread_p get source [Z]
pthread_g get source [Z]
pthread_p get source [[]
pthread_g get source [[]
pthread_p get source [\]
pthread_g get source [\]
pthread_p get source []]
pthread_g get source []]
pthread_p get source [^]
pthread_g get source [^]
pthread_p get source [_]
pthread_g get source [_]
pthread_p get source [`]
pthread_g get source [`]
pthread_p get source [a] 

示例二:用连个信号量实现有序访问

#include 
#include 
#include 
#include 
 
sem_t sem_g,sem_p;   //定义两个信号量
char ch = 'A';
char Max = 'a' ; 
char buff[256];
int i = 1;

void *pthread_g(void *arg)  //此线程改变字符ch的值
{
    while(ch < Max)
    {
        sem_wait(&sem_g);
        ch++;
        buff[i] = '>';
        //printf("\033[1B\033[K");
        //printf("%s\n", buff);
        //sleep(1);
        i++;
        sem_post(&sem_p);
    }

    return 0;
}
 
void *pthread_p(void *arg)  //此线程打印ch的值
{
	buff[0] = '>';
	//printf("\033[2B\033[K");
    while(ch < Max)
    {
        sem_wait(&sem_p);
        printf("\033[1A\033[K");
        //printf("%s  [%d%%]   %c\n", buff, i, ch);
        printf("%s  [%d%%] \n", buff, i);
        fflush(stdout);
        usleep(100000);
        sem_post(&sem_g);
    }

    return 0;
}
 
int main(int argc, char *argv[])
{
    pthread_t tid1,tid2;
    sem_init(&sem_g, 0, 0); // 初始化信号量为0
    sem_init(&sem_p, 0, 1); // 初始化信号量为1
    
    // 创建两个线程
    pthread_create(&tid1, NULL, pthread_g, NULL);
    pthread_create(&tid2, NULL, pthread_p, NULL);
    
    // 回收线程
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    
    return 0;
}

运行效果:

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  [33%]

你可能感兴趣的:(linux,c语言,linux,ipc)