#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t mutex;
void *my_thread() {
while (1) {
//判断信号量是否大于 0 ,如果大于 0 ,执行减一操作,并继续 sem_wait 之后的代码;如果当前 sem 等于 0 ,阻塞等待直至大于零
// (大于零之后执行减一操作,继续 sem_wait 之后的代码)
printf("测试数据 1");
sem_wait(&mutex);
//信号量值加一,直接返回;
printf("测试数据 2");
sem_post(&mutex);
printf("测试数据 3");
break;
}
return 0;
}
int main() {
pthread_t thread_1, thread_2; //声明线程 ID
// sem_open()创建一个新的 POSIX 信号量或打开一个现有的信号量。信号灯由名称标识。有关名称构造的详细信息,请参见 sem_overview(7)。
// oflag 参数指定用于控制调用操作的标志。 (可以通过包含来获得标志值的定义。)如果在 oflag 中指定 O_CREAT ,则如果信号灯尚不存在,则会创建该信号灯。
// 信号量的所有者(用户 ID)设置为调用过程的有效用户 ID 。组所有权(组 ID)设置为调用过程的有效组 ID 。如果在 oflag 中同时指定了 O_CREAT 和 O_EXCL ,
// 则如果已经存在具有给定名称的信号灯,则将返回错误。
// 如果在 oflag 中指定 O_CREAT ,则必须提供两个附加参数。mode 参数指定要放置在新信号量上的权限,就像 open(2)一样。
// (可以通过包含。获得权限位的符号定义。)权限设置针对进程 umask 进行掩码。应该向将访问信号量的每个用户类别都授予读取和写入权限。
// value 参数指定新信号量的初始值。如果指定了 O_CREAT ,并且已经存在具有给定名称的信号灯,则将忽略 mode 和 value
mutex = *sem_open("mutex", O_CREAT, S_IRWXU, 1);
// Name 用于标识信号量的名字
// Oflag 被设置为 O_CREAT 用来创建一个信号量(如果和 0_EXCL 一起,当这个信号量已经存在时候这个调用将会失败)
// mode_t 控制新的信号量的访问权限
// Value 指定信号量的初始化值
// ( 1 ) tidp:事先创建好的 pthread_t 类型的参数。成功时 tidp 指向的内存单元被设置为新创建线程的线程 ID 。
// ( 2 ) attr:用于定制各种不同的线程属性。APUE 的 12.3 节讨论了线程属性。通常直接设为 NULL 。
// ( 3 ) start_rtn:新创建线程从此函数开始运行。无参数是 arg 设为 NULL 即可。
// ( 4 ) arg:start_rtn 函数的参数。无参数时设为 NULL 即可。有参数时输入参数的地址。当多于一个参数时应当使用结构体传入。(以下举例)
//向线程函数传递参数
pthread_create(&thread_1, NULL, &my_thread, NULL);
pthread_create(&thread_2, NULL, &my_thread, NULL);
//以阻塞的方式等待 thread 指定的线程结束。当函数返回时,被等待线程的资源被收回。
// 如果线程已经结束,那么该函数会立即返回。并且 thread 指定的线程必须是 joinable 的
pthread_join(thread_1, NULL);
pthread_join(thread_2, NULL);
sem_unlink("mutex");
return 0;
}
```
报错是这个
zsh: segmentation fault ./a.out
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.