目录
函数接口
示例一:用一个信号量实现互斥访问
运行效果:
示例二:用连个信号量实现有序访问
运行效果:
信号量有区别于管道、消息队列等IPC,它主要是通过访问一个计数器,通过判断它的值来决定是否可以访问一个公共资源(可以是全局变量、文件等)。
定义:sem_t sem;
始化信号量:sem_init (sem_t *sem, int pshared, unsigned int value);
pshared为0表同一个进程的不同线程之间共享,这个sem值必须是线程可见的位置;如果非0,表示不同进程之间共享,它必须存在所有共享进程可以见的位置如共享内存;
value是sem的初始化值
头文件:#include
链接库:pthread
P操作:sem_wait(sem_t *sem);
判断信号量是否大于0,如果大于0,执行减一操作,并继续sem_wait之后的代码;如果当前sem等于0,阻塞等待直至大于零(大于零之后执行减一操作,继续sem_wait之后的代码)。如果深入看sem_wait的实现,它是sem_timedwait (sem_t *sem, const struct timespec *abstime)的实现,只不过这里指定的abstime为0;当然也可以用sem_timedwait指定时间来实现非阻塞操作。
V操作:sem_post(sem_t *sem);
信号量值加一,直接返回;
#include
#include
#include
#include
sem_t g_sem; //定义两个信号量
char ch = 'A';
char Max = 'a' ;
void *pthread_g(void *arg)
{
while(ch < Max)
{
sem_wait(&g_sem);
printf("%s get source [%c]\n", __func__, ch);
sem_post(&g_sem);
sleep(1);
}
return 0;
}
void *pthread_p(void *arg)
{
while(ch < Max)
{
sem_wait(&g_sem);
ch++;
printf("%s get source [%c]\n", __func__, ch);
sem_post(&g_sem);
sleep(1);
}
return 0;
}
int main(int argc, char *argv[])
{
pthread_t tid1,tid2;
sem_init(&g_sem, 0, 1); // 同一进程的不同线程的sem,初始化信号量为1
// 创建两个线程
pthread_create(&tid1, NULL, pthread_g, NULL);
pthread_create(&tid2, NULL, pthread_p, NULL);
// 回收线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
pthread_p get source [B]
pthread_g get source [B]
pthread_p get source [C]
pthread_g get source [C]
pthread_p get source [D]
pthread_g get source [D]
pthread_p get source [E]
pthread_g get source [E]
pthread_p get source [F]
pthread_g get source [F]
pthread_p get source [G]
pthread_g get source [G]
pthread_p get source [H]
pthread_g get source [H]
pthread_p get source [I]
pthread_g get source [I]
pthread_g get source [I]
pthread_p get source [J]
pthread_g get source [J]
pthread_p get source [K]
pthread_g get source [K]
pthread_p get source [L]
pthread_g get source [L]
pthread_p get source [M]
pthread_g get source [M]
pthread_p get source [N]
pthread_g get source [N]
pthread_p get source [O]
pthread_g get source [O]
pthread_p get source [P]
pthread_g get source [P]
pthread_p get source [Q]
pthread_g get source [Q]
pthread_p get source [R]
pthread_g get source [R]
pthread_p get source [S]
pthread_g get source [S]
pthread_p get source [T]
pthread_g get source [T]
pthread_p get source [U]
pthread_g get source [U]
pthread_p get source [V]
pthread_g get source [V]
pthread_p get source [W]
pthread_g get source [W]
pthread_p get source [X]
pthread_g get source [X]
pthread_p get source [Y]
pthread_g get source [Y]
pthread_p get source [Z]
pthread_g get source [Z]
pthread_p get source [[]
pthread_g get source [[]
pthread_p get source [\]
pthread_g get source [\]
pthread_p get source []]
pthread_g get source []]
pthread_p get source [^]
pthread_g get source [^]
pthread_p get source [_]
pthread_g get source [_]
pthread_p get source [`]
pthread_g get source [`]
pthread_p get source [a]
#include
#include
#include
#include
sem_t sem_g,sem_p; //定义两个信号量
char ch = 'A';
char Max = 'a' ;
char buff[256];
int i = 1;
void *pthread_g(void *arg) //此线程改变字符ch的值
{
while(ch < Max)
{
sem_wait(&sem_g);
ch++;
buff[i] = '>';
//printf("\033[1B\033[K");
//printf("%s\n", buff);
//sleep(1);
i++;
sem_post(&sem_p);
}
return 0;
}
void *pthread_p(void *arg) //此线程打印ch的值
{
buff[0] = '>';
//printf("\033[2B\033[K");
while(ch < Max)
{
sem_wait(&sem_p);
printf("\033[1A\033[K");
//printf("%s [%d%%] %c\n", buff, i, ch);
printf("%s [%d%%] \n", buff, i);
fflush(stdout);
usleep(100000);
sem_post(&sem_g);
}
return 0;
}
int main(int argc, char *argv[])
{
pthread_t tid1,tid2;
sem_init(&sem_g, 0, 0); // 初始化信号量为0
sem_init(&sem_p, 0, 1); // 初始化信号量为1
// 创建两个线程
pthread_create(&tid1, NULL, pthread_g, NULL);
pthread_create(&tid2, NULL, pthread_p, NULL);
// 回收线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> [33%]