Last Updated: 2023-07-02 14:11:12 Sunday
-- TOC --
线程间常用的同步方式,互斥量和信号量。值为1的信号量与互斥量效果一样。
pthread_mutex_t
可以定义一个mutex互斥量。
unamed semaphore is also called memory-based semaphore!
semaphore信号量与mutex不同之处在于,semaphore可以有一个大于0的值,P操作-1,V操作+1,只是不能让这个值小于0。当值为0的时候,P操作阻塞,等待另一个线程的V操作释放一个资源出来。
当semaphore的值为1时,它的行为与mutex很相似。
下面是测试代码:
$ cat test_sem_thread.c
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/wait.h>
#include <pthread.h>
#define _PEXIT \
do {\
char ebuf[64] = {0};\
sprintf(ebuf, "%s: %d", __FILE__, __LINE__);\
perror(ebuf);\
exit(errno);\
}while(0)
sem_t sem;
char *file_name = "number.txt";
void increment1(void) {
sem_wait(&sem);
int a;
FILE *fp = fopen(file_name, "r");
fscanf(fp, "%d", &a);
fclose(fp);
fp = fopen(file_name, "w");
fprintf(fp, "%d", a+1);
fclose(fp);
sem_post(&sem);
}
int main(int argc, char **argv) {
/* thread number */
int tnum;
if (argc == 2)
tnum = atoi(argv[1]);
else
tnum = 4; /* default thread number */
/* create a file which contain a number zero */
FILE *fp = fopen(file_name, "w");
if (fp == NULL)
_PEXIT;
fprintf(fp, "%d", 0);
fclose(fp);
/* init a semaphore between threads with value 1 */
if (sem_init(&sem, 0, 1) != 0)
_PEXIT;
/* create threads */
pthread_t *tid = (pthread_t*)malloc(sizeof(pthread_t)*tnum);
if (tid == NULL) {
fprintf(stderr, "malloc failed\n");
return 1;
}
pthread_t tmp_tid;
int i;
for (i=0; i<tnum; ++i) {
if (pthread_create(&tmp_tid, NULL, (void*)increment1, NULL) != 0)
_PEXIT;
tid[i] = tmp_tid;
}
/* wait all */
for (i=0; i<tnum; ++i)
pthread_join(tid[i], NULL);
/* free mem */
free(tid);
/* read out final number */
int a;
fp = fopen(file_name, "r");
fscanf(fp, "%d", &a);
fclose(fp);
printf("%d\n", a);
/* close semaphore */
sem_destroy(&sem);
/* delete file */
unlink(file_name);
return 0;
}
运行效果如下:
$ gcc -Wall -Wextra test_sem_thread.c -o test_sem_thread -lpthread
$ ./test_sem_thread
4
$ ./test_sem_thread 234
234
$ ./test_sem_thread 234567
test_sem_thread.c: 70: Resource temporarily unavailable # too many threads
$ ./test_sem_thread 2345
2345
匿名信号量也可用于进程间的同步,sem_init接口的第2个参数置1,但需要进程间存在共享内存,要将此信号量放在共享内存中。具体参考:
man 3 sem_init
本文链接:https://cs.pynote.net/sf/linux/prog/202208013/
-- EOF --
-- MORE --