互斥锁和信号量(多线程)

区别

信号量(semphore):多线程多任务同步,一个线程占用此资源后,通过信号量同步状态给别的线程。
互斥锁(Mutual exclusion):多线程多任务互斥,一个线程占用资源后,必须等待释放。(常用)
mutex是semphore一种特殊情况(n=1),后者可以代替前者。mute效率高简单,一般需要加锁的地方常用mutex。
多个线程抢锁,测试看貌似是随机抢到的。
pthread.h头文件编译命令需要添加-pthread

g++ -pthread target.cpp -o target
./target

pthread_join

使一个线程等待另一个线程结束,如果没有pthread_join,主线程会很快结束而不管其他线程执行完没,看不到打印日志

pthread_create

int pthread_create(pthread_t* restrict tidp,const pthread_attr_t* restrict_attr,void* (start_rtn)(void),void *restrict arg);
输入参数:
(1)tidp:事先创建好的pthread_t类型的参数。成功时tidp指向的内存单元被设置为新创建线程的线程ID。
(2)attr:用于定制各种不同的线程属性。APUE的12.3节讨论了线程属性。通常直接设为NULL。
(3)start_rtn:新创建线程从此函数开始运行。无参数是arg设为NULL即可。
(4)arg:start_rtn函数的参数。无参数时设为NULL即可。有参数时输入参数的地址。当多于一个参数时应当使用结构体传入。(以下举例)
返回值:成功返回0,否则返回错误码。

sem_init

该函数用于创建信号量,该函数初始化由sem指向的信号对象,设置它的共享选项,并给它一个初始的整数值value。调用成功时返回0,失败返回-1.

sem_wait

该函数用于以原子操作的方式将信号量的值减1。调用成功时返回0,失败返回-1. 如果此时&sem值为0一般会等待post操作后再获取-1;

sem_post

该函数用于以原子操作的方式将信号量的值加1
与sem_wait一样,sem指向的对象是由sem_init调用初始化的信号量。调用成功时返回0,失败返回-1.

sem_destroy

该函数用于对用完的信号量的清理。成功时返回0,失败时返回-1.

测试:

//模拟单锁多线程占用
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
char buffer[100];
pthread_mutex_t mutex;
sem_t sem;
void * getService(void *thread_id)
{
        for(int ii=0;ii<5;ii++)
        {
                pthread_mutex_lock(&mutex);  //上锁
                //sem_wait(&sem);
                printf("[%d]:[time%d][%d]locked..\n", time(0),ii,(int*)thread_id);
                printf("----------------------------thread[%lld]\n", pthread_self());
                sleep(2);
                pthread_mutex_unlock(&mutex);  //解锁
                //sem_post(&sem);
                printf("[%d]:[time%d][%d]unlocked...thread[%lld]\n",time(0),ii,(int*)thread_id,pthread_self());
                usleep(10);
        }
}

int main(int argc,char *argv[])
{
        pthread_mutex_init(&mutex,NULL);
        //sem_init(&sem,0,1);
        pthread_t pthread1,pthread2;
        pthread_create(&pthread1,NULL,getService,(void*)1);
        pthread_create(&pthread2,NULL,getService,(void*)2);
        pthread_join(pthread1,NULL);
        pthread_join(pthread2,NULL);
        pthread_mutex_destroy(&mutex);
        //sem_destroy(&sem);
        return 0;
}
测试结果:
[1648385214]:[time0][2]locked..
----------------------------thread[139804196894464]
[1648385216]:[time0][2]unlocked...thread[139804196894464]
[1648385216]:[time0][1]locked..
----------------------------thread[139804205287168]
[1648385218]:[time0][1]unlocked...thread[139804205287168]
[1648385218]:[time1][1]locked..
----------------------------thread[139804205287168]
[1648385220]:[time1][1]unlocked...thread[139804205287168]
[1648385220]:[time1][2]locked..
----------------------------thread[139804196894464]
[1648385222]:[time1][2]unlocked...thread[139804196894464]
[1648385222]:[time2][1]locked..
----------------------------thread[139804205287168]
[1648385224]:[time2][1]unlocked...thread[139804205287168]
[1648385224]:[time2][2]locked..
----------------------------thread[139804196894464]
[1648385226]:[time2][2]unlocked...thread[139804196894464]
[1648385226]:[time3][1]locked..
----------------------------thread[139804205287168]
[1648385228]:[time3][1]unlocked...thread[139804205287168]
[1648385228]:[time3][2]locked..
----------------------------thread[139804196894464]
[1648385230]:[time3][2]unlocked...thread[139804196894464]
[1648385230]:[time4][1]locked..
----------------------------thread[139804205287168]
[1648385232]:[time4][1]unlocked...thread[139804205287168]
[1648385232]:[time4][2]locked..
----------------------------thread[139804196894464]
[1648385234]:[time4][2]unlocked...thread[139804196894464]
//信号量模拟多顾客少前台
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#define CUSTOMER_NUM 10   //顾客数
#define WIN_NUM 3   //窗口数
sem_t sem;
void * getService(void *thread_id)
{
        int cusId = *((int *)thread_id);
        int sem_w = sem_wait(&sem);
        printf("sem_w:[%d]",sem_w);
        if (sem_w>=0)
        {
                sleep(3);
                sem_post(&sem);
        }
        else
        {
                printf("sem_wait not wait\n");
        }
}

int main(int argc,char *argv[])
{
        sem_init(&sem, 0, WIN_NUM);  //三个窗口
        pthread_t pCustomer[CUSTOMER_NUM];
        for (int i=0;i< CUSTOMER_NUM;i++)
        {
                int Cusid = i;
                int ret = pthread_create(&pCustomer[i],NULL, getService, &Cusid);
                if (ret != 0)
                {
                        printf("pthread_create error");
                        exit(1);
                }
                else
                {
                        printf("Customer [%d] arrived \n", i);
                }
                usleep(10);
        }
        for (int j=0;j< CUSTOMER_NUM;j++)
        {
                pthread_join(pCustomer[j],NULL);
        }
        sem_destroy(&sem);

        return 0;
}

测试结果:
Customer [0] arrived 
Customer [1] arrived 
sem_w:[0]==== customer [1] getService time:[1648386326] ==== 
Customer [2] arrived 
sem_w:[0]==== customer [2] getService time:[1648386326] ==== 
Customer [3] arrived 
sem_w:[0]==== customer [3] getService time:[1648386326] ==== 
Customer [4] arrived 
Customer [5] arrived 
Customer [6] arrived 
Customer [7] arrived 
Customer [8] arrived 
Customer [9] arrived 
sem_w:[0]==== customer [4] getService time:[1648386329] ==== 
sem_w:[0]==== customer [4] getService time:[1648386329] ==== 
sem_w:[0]==== customer [5] getService time:[1648386329] ==== 
sem_w:[0]==== customer [6] getService time:[1648386332] ==== 
sem_w:[0]==== customer [7] getService time:[1648386332] ==== 
sem_w:[0]==== customer [8] getService time:[1648386332] ==== 
sem_w:[0]==== customer [9] getService time:[1648386335] ====
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值