使用信号量要求多个线程之间的执行顺序
对于同步和互斥,使用信号量或互斥量都可以实现。
使用时,选择更符合语义的手段:
如果要求最多只允许一个线程进入临界区,则使用互斥量
如果要求多个线程之间的执行顺序满足某个约束,则使用信号量
创建2个线程(共有主线程、线程1、线程2共3个线程),主线程阻塞式等待用户输入字符串,主线程每接收到一个字符串之后, 线程1就马上对该字符串进行处理。
线程1的处理逻辑为:统计该字符串的个数,并记录当时的时间。
线程1把该字符串处理完后,线程2马上就把处理结果写入文件result.txt
直到用户输入exit.
代码:
#include <stdio.h>
#include<stdlib.h>
#include <pthread.h>
#include<unistd.h>
#include <string.h>
#include <time.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 64
char buff[N];
char temp[N];
char ex[N];
sem_t sem1;
sem_t sem2;
sem_t sem3;
void* my_thread1(void* arg)
{
clock_t tm;
while (1) {
//处理字符串
sem_wait(&sem2);
memcpy(ex, buff, strlen(buff));
tm = clock();
sprintf(buff, "%-3u", (unsigned int)strlen(buff));
sprintf(temp, "%ld", (long)tm);
memcpy(buff + strlen(buff), temp, strlen(temp));
//printf("buff thread1: %s\n", buff);
sem_post(&sem3);
if (strncmp(ex, "exit", 4) == 0) {
break;
}
}
}
void* my_thread2(void* arg)
{
//打开文件
int fd = open("./result.txt", O_RDWR | O_CREAT, 0666);
while (1) {
sem_wait(&sem3);
//printf("buff strel: %d\n", strlen(buff));
if (strncmp(ex, "exit", 4) == 0) {
break;
}
int ret = write(fd, buff, strlen(buff));
memset(buff, sizeof(buff),0);
if (ret == -1) {
printf("write failed.\n");
exit(1);
}
//printf("thread2 buff: %s\n", buff);
sem_post(&sem1);
}
close(fd);
}
int main()
{
pthread_t c, p;//两个线程
//初始化
sem_init(&sem1, 0, 1);
sem_init(&sem2, 0, 0);
sem_init(&sem3, 0, 0);
pthread_create(&p, NULL, my_thread1, NULL);
pthread_create(&c, NULL, my_thread2, NULL);
while (1) {
//P
sem_wait(&sem1);
fgets(buff, sizeof(buff), stdin);
//V
//printf("main buff: %s\n", buff);
sem_post(&sem2);
if (strncmp(buff, "exit", 4) == 0) {
break;
}
}
pthread_join(p, NULL);
pthread_join(c, NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
return 0;
}