信号量sem_t,互斥锁pthread_mutex_t的使用

        信号量的数据类型为结构sem_t,它本质上是一个长整型的数。

------函数sem_init()用来初始化一个信号量。

       它的原型为: extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));

sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。

-----函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。 

-----函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。

-----函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。

-----函数sem_destroy(sem_t *sem)用来释放信号量sem

(1)信号量用sem_init函数创建的,下面是它的说明:
  #include<semaphore.h>
        int sem_init (sem_t *sem, int pshared, unsigned int value);
        这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。pshared参数控制着信号量的类型。如果 pshared的值是0,就表示它是当前里程的局部信号量;否则,其它进程就能够共享这个信号量。我们现在只对不让进程共享的信号量感兴趣。 (这个参数受版本影响), pshared传递一个非零将会使函数调用失败。
(2)这两个函数控制着信号量的值,它们的定义如下所示:
  
  #include <semaphore.h>
        int sem_wait(sem_t * sem);
        int sem_post(sem_t * sem);
 
        这两个函数都要用一个由sem_init调用初始化的信号量对象的指针做参数。
        sem_post函数的作用是给信号量的值加上一个“1”,它是一个“原子操作"即同时对同一个信号量做加“1”操作的两个线程是不会冲突的;而同时对同一个文件进行读、加和写操作的两个程序就有可能会引起冲突。信号量的值永远会正确地加一个“2”--因为有两个线程试图改变它。
        sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,信号量的值将减到1。如果对一个值为0的信号量调用sem_wait(),这个函数就会地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。
         信号量这种“只用一个函数就能原子化地测试和设置”的能力下正是它的价值所在。还有另外一个信号量函数sem_trywait,它是sem_wait的非阻塞搭档。
    (3)  最后一个信号量函数是sem_destroy。这个函数的作用是在我们用完信号量对它进行清理。下面的定义:
          #include<semaphore.h>
          int sem_destroy (sem_t *sem);
          这个函数也使用一个信号量指针做参数,归还自己占据的一切资源。在清理信号量的时候如果还有线程在等待它,用户就会收到一个错误。
         与其它的函数一样,这些函数在成功时都返回“0”。

********************************************************************************************************

程序举例如下:
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <pthread.h>  //包含线程相关头文件
#include <errno.h> 
#include <sys/ipc.h> 
#include <semaphore.h>  //包含信号量相关头文件
int lock_var; 
time_t end_time; 
sem_t sem1,sem2;  //声明两个信号量
 

void pthread1(void *arg);  //声明两个线程函数
void pthread2(void *arg); 
 
int main(int argc, char *argv[]) 

    pthread_t id1,id2;  //声明两个线程
    pthread_t mon_th_id; 
    int ret; 
    end_time = time(NULL)+30; 
    ret=sem_init(&sem1,0,1);  //对信号量进行初始化,第一个0表示此信号量子整个进程中共享,第二个1表示信号量初始值
    ret=sem_init(&sem2,0,0); 
    if(ret!=0) 
    { 
        perror("sem_init"); 
    } 
    ret=pthread_create(&id1,NULL,(void *)pthread1, NULL);  //创建线程
    if(ret!=0) 
        perror("pthread cread1"); 
    ret=pthread_create(&id2,NULL,(void *)pthread2, NULL); 
    if(ret!=0) 
        perror("pthread cread2"); 
    pthread_join(id1,NULL);  //用来等待线程1的结束
    pthread_join(id2,NULL);  //用来等待线程2的结束
    exit(0); 

 
void pthread1(void *arg)  //线程1的执行内容

    int i; 
    while(time(NULL) < end_time){ 
        sem_wait(&sem2);  //线程阻塞一直等到sem2信号量大于0,执行后将sem2减1,代表资源已经被使用
        for(i=0;i<2;i++){ 
            sleep(1); 
            lock_var++; 
            printf("lock_var=%d\n",lock_var); 
        } 
        printf("pthread1:lock_var=%d\n",lock_var); 
        sem_post(&sem1);  //将信号量sem1的值加1,代表资源增加
        sleep(1); 
    } 

 
void pthread2(void *arg) 

    int nolock=0; 
    int ret; 
    while(time(NULL) < end_time){ 
    sem_wait(&sem1); 
    printf("pthread2:pthread1 got lock;lock_var=%d\n",lock_var); 
    sem_post(&sem2); 
    sleep(3); 
    } 

 
信号量的使用如下步骤小结:
 1.声明信号量sem_t sem1;
 2.初始化信号量sem_init(&sem1,0,1); /
 3.sem_post和sem_wait函数配合使用来达到线程同步
 4.释放信号量int sem_destroy (sem_t *sem1);


#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <semaphore.h> #include <pthread.h> sem_t apple; sem_t orange; sem_t empty; pthread_mutex_t mutex; void *Dad() { int nextp = 0; int i = 0; for(i = 0; i < 10; ++i) { int time = rand() % 10 + 1; //随机使程序睡眠0点几秒 usleep(time*100000); sem_wait(&empty); pthread_mutex_lock(&mutex); if(nextp == 0) { printf("爸爸放入了一个苹果\n"); } else { printf("爸爸放入了一个桔子\n"); } fflush(stdout); pthread_mutex_unlock(&mutex); //互斥锁解锁 if(nextp == 0) { sem_post(&apple); } else { sem_post(&orange); } nextp = 1 - nextp; } } void *Daughter() { while(1) { int time = rand() % 10 + 1; //随机使程序睡眠0点几秒 usleep(time * 100000); sem_wait(&apple); pthread_mutex_lock(&mutex); printf("女儿取了一个苹果\n") ; fflush(stdout); pthread_mutex_unlock(&mutex); //互斥锁解锁 sem_post(&empty); } } void *Son() { while(1) { int time=rand()%10+1; usleep(time*10000); sem_wait(&orange); pthread_mutex_lock(&mutex); printf("儿子取了一个桔子\n") ; fflush(stdout); pthread_mutex_unlock(&mutex); sem_post(&empty); } //请添加儿子线程的函数代码 } int main() { sem_init(&empty, 0, 5); //信号量初始化 sem_init(&orange, 0, 0); sem_init(&apple, 0, 0); pthread_mutex_init(&mutex, NULL); //互斥锁初始化 pthread_t dadid; pthread_t daughterid; pthread_t sonid; pthread_create(&dadid, NULL, Dad, NULL); //创建爸爸线程 pthread_create(&daughterid, NULL, Daughter, NULL); //创建女儿线程 pthread_create(&sonid, NULL, Son, NULL); //创建儿子线程 pthread_join(daughterid, NULL); pthread_join(sonid, NULL); sem_destroy(&empty); //信号量的销毁 sem_destroy(&apple); sem_destroy(&orange); pthread_mutex_destroy(&mutex); //互斥锁的销毁 return 0; } 帮我注释每一条代码
03-26
#include <stdio.h> #include <pthread.h> #include <errno.h> #include <signal.h> #include <unistd.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/ipc.h> #include "data_global.h" extern pthread_cond_t cond_sqlite; extern pthread_cond_t cond_analysis; extern pthread_cond_t cond_client_send; extern pthread_cond_t cond_uart_cmd; extern pthread_cond_t cond_client_request; extern pthread_cond_t cond_infrared; extern pthread_cond_t cond_buzzer; extern pthread_cond_t cond_led; extern pthread_cond_t cond_camera; extern pthread_cond_t cond_sms; extern pthread_cond_t cond_refresh; extern pthread_cond_t cond_refresh_updata; extern pthread_mutex_t mutex_slinklist; extern pthread_mutex_t mutex_sqlite; extern pthread_mutex_t mutex_analysis; extern pthread_mutex_t mutex_client_send; extern pthread_mutex_t mutex_client_receive; extern pthread_mutex_t mutex_uart_cmd; extern pthread_mutex_t mutex_client_request; extern pthread_mutex_t mutex_infrared; extern pthread_mutex_t mutex_buzzer; extern pthread_mutex_t mutex_led; extern pthread_mutex_t mutex_camera; extern pthread_mutex_t mutex_sms; extern pthread_mutex_t mutex_refresh; extern pthread_mutex_t mutex_refresh_updata; extern pthread_mutex_t mutex_global; extern pthread_mutex_t mutex_linklist; extern int dev_infrared_fd; extern int dev_buzzer_fd; extern int dev_led_fd; extern int dev_camera_fd; extern int dev_sms_fd; extern int dev_uart_fd; extern int msgid; extern int shmid; extern int semid; extern void Create_table (); extern struct env_info_clien_addr all_info_RT; pthread_t id_sqlite, id_analysis, id_transfer, id_client_send, id_client_receive, id_uart_cmd, id_client_request, id_infrared, id_buzzer, id_led, id_camera, id_sms, id_refresh; void ReleaseResource (int signo) { pthread_mutex_destroy (&mutex_linklist); pthread_mutex_destroy (&mutex_global); pthread_mutex_destroy (&mutex_refresh_updata); pthread_mutex_destroy (&mutex_refresh); pthread_mutex_destroy (&mutex_sms); pthread_mutex_destroy (&mutex_camera); pthread_mutex_destroy (&mutex_led); pthread_mutex_destroy (&mutex_buzzer); pthread_mutex_destroy (&mutex_infrared); pthread_mutex_destroy (&mutex_client_request); pthread_mutex_destroy (&mutex_uart_cmd); pthread_mutex_destroy (&mutex_analysis); pthread_mutex_destroy (&mutex_client_send); pthread_mutex_destroy (&mutex_client_receive); pthread_mutex_destroy (&mutex_sqlite); pthread_mutex_destroy (&mutex_slinklist); pthread_cond_destroy (&cond_client_send); pthread_cond_destroy (&cond_refresh_updata); pthread_cond_destroy (&cond_refresh); pthread_cond_destroy (&cond_sms); pthread_cond_destroy (&cond_camera); pthread_cond_destroy (&cond_led); pthread_cond_destroy (&cond_buzzer); pthread_cond_destroy (&cond_infrared); pthread_cond_destroy (&cond_client_request); pthread_cond_destroy (&cond_uart_cmd); pthread_cond_destroy (&cond_analysis); pthread_cond_destroy (&cond_sqlite); msgctl (msgid, IPC_RMID, NULL); shmctl (shmid, IPC_RMID, NULL); pthread_cancel (id_refresh); pthread_cancel (id_sms); pthread_cancel (id_camera); pthread_cancel (id_led); pthread_cancel (id_buzzer); pthread_cancel (id_infrared); pthread_cancel (id_client_request); pthread_cancel (id_uart_cmd); pthread_cancel (id_transfer); pthread_cancel (id_analysis); pthread_cancel (id_client_send); pthread_cancel (id_client_receive); pthread_cancel (id_sqlite); close (dev_camera_fd); close (dev_led_fd); close (dev_buzzer_fd); close (dev_infrared_fd); close (dev_sms_fd); close (dev_uart_fd); printf ("All quit\n"); exit(0); } void setLimit (int sto_no, float temMAX, float temMIN, float humMAX, float humMIN, float illMAX, float illMIN) { if (sto_no >= 0 && (sto_no <=STORAGE_NUM - 1)) { all_info_RT.storage_no[sto_no].temperatureMAX = temMAX; all_info_RT.storage_no[sto_no].temperatureMIN = temMIN; all_info_RT.storage_no[sto_no].humidityMAX = humMAX; all_info_RT.storage_no[sto_no].humidityMIN = humMIN; all_info_RT.storage_no[sto_no].illuminationMAX = illMAX; all_info_RT.storage_no[sto_no].illuminationMIN = illMIN; } } int main(int argc, char **argv) { #if 1 / Create_table (); // setLimit (1, 50, 5, 50, 10, 500, 10); setLimit (2, 50, 5, 50, 10, 500, 10); pthread_mutex_init (&mutex_slinklist, NULL);// pthread_mutex_init (&mutex_sqlite, NULL); pthread_mutex_init (&mutex_analysis, NULL); pthread_mutex_init (&mutex_uart_cmd, NULL); pthread_mutex_init (&mutex_client_request, NULL); pthread_mutex_init (&mutex_infrared, NULL); pthread_mutex_init (&mutex_buzzer, NULL); pthread_mutex_init (&mutex_led, NULL); pthread_mutex_init (&mutex_camera, NULL); pthread_mutex_init (&mutex_sms, NULL); pthread_mutex_init (&mutex_refresh, NULL); pthread_mutex_init (&mutex_refresh_updata, NULL); pthread_mutex_init (&mutex_global, NULL); pthread_mutex_init (&mutex_linklist, NULL); pthread_mutex_init (&mutex_client_send, NULL); pthread_cond_init (&cond_client_send, NULL); pthread_cond_init (&cond_sqlite, NULL); pthread_cond_init (&cond_analysis, NULL); pthread_cond_init (&cond_uart_cmd, NULL); pthread_cond_init (&cond_client_request, NULL); pthread_cond_init (&cond_infrared, NULL); pthread_cond_init (&cond_buzzer, NULL); pthread_cond_init (&cond_led, NULL); pthread_cond_init (&cond_camera, NULL); pthread_cond_init (&cond_sms, NULL); pthread_cond_init (&cond_refresh, NULL); pthread_cond_init (&cond_refresh_updata, NULL); //signal (SIGINT, ReleaseResource); // pthread_create (&id_sqlite, 0, pthread_sqlite, NULL); sleep (1); pthread_create (&id_analysis, 0, pthread_analysis, NULL); pthread_create (&id_client_send, 0, pthread_client_send, NULL); pthread_create (&id_transfer, 0, pthread_transfer, NULL); sleep (1); pthread_create (&id_uart_cmd, 0, pthread_uart_cmd, NULL); pthread_create (&id_client_request, 0, pthread_client_request, NULL); pthread_create (&id_infrared, 0, pthread_infrared, NULL); pthread_create (&id_buzzer, 0, pthread_buzzer, NULL); pthread_create (&id_led, 0, pthread_led, NULL); pthread_create (&id_camera, 0, pthread_camera, NULL); pthread_create (&id_sms, 0, pthread_sms, NULL); pthread_create (&id_refresh, 0, pthread_refresh, NULL); // pthread_join (id_sqlite, NULL); pthread_join (id_client_send, NULL); printf ("g1\n"); pthread_join (id_analysis, NULL); printf ("g2\n"); pthread_join (id_transfer, NULL); printf ("g3\n"); pthread_join (id_uart_cmd, NULL); printf ("g4\n"); pthread_join (id_client_request, NULL); printf ("g5\n"); pthread_join (id_infrared, NULL); printf ("g6\n"); pthread_join (id_buzzer, NULL); printf ("g7\n"); pthread_join (id_led, NULL); printf ("g8\n"); pthread_join (id_camera, NULL); printf ("g9\n"); pthread_join (id_sms, NULL); printf ("g10\n"); pthread_join (id_refresh, NULL); printf ("g11\n"); return 0; }
最新发布
07-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值