区别
信号量(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] ====
3883

被折叠的 条评论
为什么被折叠?



