国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux線程的信號量同步

2024-06-28 13:21:30
字體:
來源:轉載
供稿:網友
linux線程的信號量同步

信號量和互斥鎖(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 <pthread.h>#include <semaphore.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>/* @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 .../n", customer_id);        sem_post(&sem);    }}#define CUSTOMER_NUM 10int 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./n", 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 ...

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 赤城县| 武乡县| 慈溪市| 浏阳市| 梁河县| 略阳县| 临武县| 湘乡市| 紫阳县| 康平县| 玉田县| 和龙市| 景泰县| 邢台县| 华容县| 肃宁县| 叙永县| 克山县| 佛坪县| 横峰县| 揭东县| 梁平县| 民权县| 宝丰县| 呼玛县| 石嘴山市| 襄汾县| 昌黎县| 西华县| 丹凤县| 德化县| 通化县| 子长县| 周宁县| 太白县| 瓮安县| 阳西县| 余干县| 和平区| 南宁市| 永平县|