螃蟹分享站:专注做好分享站 www.ahjiajia.com!
游戏
热门搜索:老有坏人想害我,搜索功能取消
您当前所在位置:首页 >软件教程 >应用教程

Linux线程的信号量同步

时间:2024-08-30 09:18 来源:网络

系统大全为您提供

信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区。

不多做解释,要使用信号量同步,需要包含头文件semaphore.h。

主要用到的函数:

int sem_init(sem_t *sem, int pshared, unsigned int value);,其中sem是要初始化的信号量,pshared表示此信号量是在进程间共享还是线程间共享,value是信号量的初始值。

int sem_destroy(sem_t *sem);,其中sem是要销毁的信号量。只有用sem_init初始化的信号量才能用sem_destroy销毁。

int sem_wait(sem_t *sem);等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1。

int sem_post(sem_t *sem); 释放信号量,让信号量的值加1。相当于V操作。

下列的代码演示了如何用信号量同步,模拟一个窗口服务系统。

/* @purpose: 基于信号量的多线程同步,操作系统原理中的P,V操作

 * @author: jollywing@foxmail.com

 * @create: 2015-03-20 Fri

 * */

 

#include

#include

#include

#include

#include

 

 

/* @Scene: 某行业营业厅同时只能服务两个顾客。

 * 有多个顾客到来,每个顾客如果发现服务窗口已满,就等待,

 * 如果有可用的服务窗口,就接受服务。 */

 

/* 将信号量定义为全局变量,方便多个线程共享 */

sem_t sem;

 

/* 每个线程要运行的例程 */

void * get_service(void *thread_id)

{

    /* 注意:立即保存thread_id的值,因为thread_id是对主线程中循环变量i的引用,它可能马上被修改 */

    int customer_id = *((int *)thread_id);

 

    if(sem_wait(&sem) == 0) {

        usleep(100);                /* service time: 100ms */

        printf("customer %d receive service ...", customer_id);

        sem_post(&sem);

    }

}

 

#define CUSTOMER_NUM 10

 

int main(int argc, char *argv[])

{

    /* 初始化信号量,初始值为2,表示有两个顾客可以同时接收服务 */

    /* @prototype: int sem_init(sem_t *sem, int pshared, unsigned int value); */

    /* pshared: if pshared == 0, the semaphore is shared among threads of a process

     * otherwise the semaphore is shared between processes.   */

    sem_init(&sem, 0, 2);

 

    /* 为每个顾客定义一个线程id, pthread_t 其实是unsigned long int */

    pthread_t customers[CUSTOMER_NUM];

 

    int i, ret;

    /* 为每个顾客生成一个线程 */

    for(i = 0; i < CUSTOMER_NUM; i++){

        int customer_id = i;

        ret = pthread_create(&customers[i], NULL, get_service, &customer_id);

        if(ret != 0){

            perror("pthread_create");

            exit(1);

        }

        else {

            printf("Customer %d arrived.", i);

        }

        usleep(10);

    }

 

    /* 等待所有顾客的线程结束 */

    /* 注意:这地方不能再用i做循环变量,因为可能线程中正在访问i的值 */

    int j;

    for(j = 0; j < CUSTOMER_NUM; j++) {

        pthread_join(customers[j], NULL);

    }

 

    /* Only a  semaphore that  has been initialized  by sem_init(3)

     * should be destroyed using sem_destroy().*/

    sem_destroy(&sem);

    return 0;

}

编译:gcc main.c -lpthread。

运行结果(注意,每次运行都不相同):

Customer 0 arrived.

Customer 1 arrived.

customer 0 receive service ...

Customer 2 arrived.

customer 1 receive service ...

Customer 3 arrived.

customer 2 receive service ...

Customer 4 arrived.

customer 3 receive service ...

Customer 5 arrived.

customer 4 receive service ...

Customer 6 arrived.

customer 5 receive service ...

Customer 7 arrived.

customer 6 receive service ...

Customer 8 arrived.

customer 7 receive service ...

Customer 9 arrived.

customer 8 receive service ...

customer 9 receive service ...

 

 

  以上就是系统大全给大家介绍的如何使的方法都有一定的了解了吧,好了,如果大家还想了解更多的资讯,那就赶紧点击系统大全官网吧。 

 

本文来自系统大全http://www.win7cn.com/如需转载请注明!推荐:win7纯净版

相关应用
搬运帮工人版
135.4 MB / 2.2.6
遵义公交
69.8 MB / V2.3.4
车拖车司机
116 MB / 3.4.8
左邻右家
45.6 MB / 4.5.5
慧享家
72.3 MB / 7.1.0
优居找房
106.9 MB / 4.9.0
宿迁党员e家
47.7 MB / 8.2.0
新疆智慧人社
69.1 MB / 3.2.5
锂纳斯换电
111.3 MB / 1.80.35
校园汇生活
29.2 MB / 2.3.7
小云天气
12.3 MB / 5.6.8
婚语
39.5 MB / V5.3.5
苏证通
38.9 MB / 3.8.10
七彩天气
63.5 MB / 3.32
Wellcee
98.3 MB / 4.15.1