- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有没有办法确保只有 1 个线程执行特定功能?
for (i = startnotfirst; i < end; i++) {
gl_rand = (float) lrand48();
fprintf(stderr, "\nTHREADING - #ID: %d - THIS IS MY RAND: %f", *mytid,rand);
to_open = (rand / (float) INT_MAX) < (points->p[i].cost / z);
if (to_open) {
//printf("\nRANDOM: %f \nINT_MAX: %d \npointsDistance(cost): %f \nZ: %f \n\n RESULT: %f < %f\n\n\n",rand ,INT_MAX,points->p[1].cost , z,(rand / (float) INT_MAX),(points->p[i].cost / z));
fprintf(stderr, "\nTHREADING - #ID: %d - im working...", *mytid);
t_kcenter++;
for (int k = start; k < end; k++) {
float distance = dist(points->p[i], points->p[k], points->dim);
//If distance is smaller add it to that cluster.
float new_cost = distance * points->p[k].weight;
if (new_cost < points->p[k].cost) {
points->p[k].cost = new_cost;
points->p[k].assign = i;
}
}
}
}
global variable
知道新的 rand 值。或
broadcasting
.
iteration body
在新号码出来之前!
最佳答案
pthread_cond_wait()
和 pthread_cond_broadcast()
结合 pthread_mutex_lock()
pthread_mutex_unlock()
, 这
pthread_cond_wait()
和
pthread_cond_broadcast()
功能是实现所需功能的关键。
但是,要使谓词正确,需要相当小心。
/*
** Objective: N threads cooperate on M cycles or iterations of a task.
** A new random number is needed for each cycle, but all threads must
** use the same random number on each cycle.
** Any thread may evaluate the new random number.
*/
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "stderr.h"
#ifndef NUM_THREADS
#define NUM_THREADS 3
#endif
#ifndef NUM_CYCLES
#define NUM_CYCLES 5
#endif
enum { MAX_THREADS = NUM_THREADS };
enum { MAX_CYCLES = NUM_CYCLES };
static pthread_mutex_t mtx_waiting = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cnd_waiting = PTHREAD_COND_INITIALIZER;
static int num_waiting = 0;
static int cycle = -1;
static float gl_rand = 0;
static long gl_long = 0;
static float next_iteration_random_number(int tid, int iteration)
{
pthread_mutex_lock(&mtx_waiting);
assert(cycle == iteration || cycle == iteration - 1);
num_waiting++;
printf("-->> TID %d, I = %d (C = %d, W = %d)\n",
tid, iteration, cycle, num_waiting);
while (cycle != iteration && num_waiting != MAX_THREADS)
{
assert(num_waiting > 0 && num_waiting <= MAX_THREADS);
printf("-CW- TID %d, I = %d (C = %d, W = %d)\n",
tid, iteration, cycle, num_waiting);
pthread_cond_wait(&cnd_waiting, &mtx_waiting);
}
assert(cycle == iteration || num_waiting == MAX_THREADS);
printf("---- TID %d, I = %d (C = %d, W = %d)\n",
tid, iteration, cycle, num_waiting);
if (cycle != iteration)
{
gl_long = lrand48();
gl_rand = (float)gl_long;
num_waiting = 0;
cycle = iteration;
printf("---- TID %d generates cycle %d: L = %ld, F = %g\n",
tid, cycle, gl_long, gl_rand);
pthread_cond_broadcast(&cnd_waiting);
}
printf("<<-- TID %d, I = %d (C = %d, W = %d) L = %ld, F = %g\n",
tid, iteration, cycle, num_waiting, gl_long, gl_rand);
pthread_mutex_unlock(&mtx_waiting);
return gl_rand;
}
static void *thread_function(void *vp)
{
int tid = (int)(uintptr_t)vp; // Thuggish!
for (int i = 0; i < MAX_CYCLES; i++)
{
float f = next_iteration_random_number(tid, i);
printf("TID %d at work: I = %d, F = %g\n", tid, i, f);
fflush(stdout);
struct timespec rq;
rq.tv_sec = 0;
rq.tv_nsec = (((gl_long & 0xFF) + (0xF * tid))) % 200 * 50000000;
assert(rq.tv_nsec >= 0 && rq.tv_nsec < 10000000000);
nanosleep(&rq, 0);
}
return 0;
}
int main(int argc, char **argv)
{
err_setarg0(argv[0]);
assert(argc == 1);
pthread_t thread[MAX_THREADS];
for (int i = 0; i < MAX_THREADS; i++)
{
int rc = pthread_create(&thread[i], 0, thread_function, (void *)(uintptr_t)i);
if (rc != 0)
{
errno = rc;
err_syserr("failed to create thread %d", i);
}
}
for (int i = 0; i < MAX_THREADS; i++)
{
void *vp;
int rc = pthread_join(thread[i], &vp);
if (rc != 0)
{
errno = rc;
err_syserr("Failed to join TID %d", i);
}
printf("TID %d returned %p\n", i, vp);
}
return 0;
}
libsoq
中的库代码.例程开始
err_
在标题
stderr.h
中声明支持代码在
stderr.c
.这些大大简化了错误报告。
main()
功能微不足道;它启动 5 个线程,然后等待加入 5 个线程。唯一棘手的一点是将线程号作为参数传递给线程函数。该代码将整数值转换为
uintptr_t
,然后将其强制为
void *
;被调用函数撤消此序列
next_iteration_random_number()
,它协调随机数的生成。线程打印数据,然后使用
nanosleep()
sleep 时间少于 1 秒,不易辨认。
next_iteration_random_number()
.首先,线程锁定控制共享信息的互斥锁。然后它增加等待线程的数量。如果当前循环与其正在处理的迭代不同,并且等待线程数不等于线程总数,则该线程调用
pthread_cond_wait()
sleep 直到广播到。当线程退出循环时(通过在广播后唤醒,或者因为它从未进入循环),线程查看当前循环是否是它所期望的迭代。如果不是,它必须是这个循环中尝试的最后一个线程——所以它会生成随机数并进行内务处理以确保其他线程知道发生了什么,
pthread_cond_broadcast()
通知所有 sleep 线程唤醒。他们实际上还不能醒来;当前线程仍然持有互斥锁。它报告它正在做什么并解锁互斥锁,并返回随机数。其他线程检测到循环编号与它们等待的迭代相同,因此它们可以各自打印信息、解锁互斥体并返回编号。
lrand48()
返回
long
(尽管值在 [0,231 范围内),因此即使
long
时它也是 32 位值是 64 位类型),这意味着它很有可能返回无法在
float
中准确表示的值,所以
gl_rand = (float)lrand48();
从问题中截取的代码是可疑的。 (示例代码还将
long
值记录在
gl_long
中,并且偶尔会使用它。)
$ gcc -O3 -g -I../../inc -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition pthrd37.c -o pthrd37 \
> -L../../lib -lsoq
$
-->> TID 0, I = 0 (C = -1, W = 1)
-CW- TID 0, I = 0 (C = -1, W = 1)
-->> TID 2, I = 0 (C = -1, W = 2)
-CW- TID 2, I = 0 (C = -1, W = 2)
-->> TID 1, I = 0 (C = -1, W = 3)
---- TID 1, I = 0 (C = -1, W = 3)
---- TID 1 generates cycle 0: L = 851401618, F = 8.51402e+08
<<-- TID 1, I = 0 (C = 0, W = 0) L = 851401618, F = 8.51402e+08
TID 1 at work: I = 0, F = 8.51402e+08
---- TID 0, I = 0 (C = 0, W = 0)
<<-- TID 0, I = 0 (C = 0, W = 0) L = 851401618, F = 8.51402e+08
TID 0 at work: I = 0, F = 8.51402e+08
---- TID 2, I = 0 (C = 0, W = 0)
<<-- TID 2, I = 0 (C = 0, W = 0) L = 851401618, F = 8.51402e+08
TID 2 at work: I = 0, F = 8.51402e+08
-->> TID 1, I = 1 (C = 0, W = 1)
-CW- TID 1, I = 1 (C = 0, W = 1)
-->> TID 0, I = 1 (C = 0, W = 2)
-CW- TID 0, I = 1 (C = 0, W = 2)
-->> TID 2, I = 1 (C = 0, W = 3)
---- TID 2, I = 1 (C = 0, W = 3)
---- TID 2 generates cycle 1: L = 1804928587, F = 1.80493e+09
<<-- TID 2, I = 1 (C = 1, W = 0) L = 1804928587, F = 1.80493e+09
TID 2 at work: I = 1, F = 1.80493e+09
---- TID 1, I = 1 (C = 1, W = 0)
<<-- TID 1, I = 1 (C = 1, W = 0) L = 1804928587, F = 1.80493e+09
TID 1 at work: I = 1, F = 1.80493e+09
---- TID 0, I = 1 (C = 1, W = 0)
<<-- TID 0, I = 1 (C = 1, W = 0) L = 1804928587, F = 1.80493e+09
TID 0 at work: I = 1, F = 1.80493e+09
-->> TID 2, I = 2 (C = 1, W = 1)
-CW- TID 2, I = 2 (C = 1, W = 1)
-->> TID 1, I = 2 (C = 1, W = 2)
-CW- TID 1, I = 2 (C = 1, W = 2)
-->> TID 0, I = 2 (C = 1, W = 3)
---- TID 0, I = 2 (C = 1, W = 3)
---- TID 0 generates cycle 2: L = 758783491, F = 7.58783e+08
<<-- TID 0, I = 2 (C = 2, W = 0) L = 758783491, F = 7.58783e+08
TID 0 at work: I = 2, F = 7.58783e+08
---- TID 2, I = 2 (C = 2, W = 0)
<<-- TID 2, I = 2 (C = 2, W = 0) L = 758783491, F = 7.58783e+08
TID 2 at work: I = 2, F = 7.58783e+08
---- TID 1, I = 2 (C = 2, W = 0)
<<-- TID 1, I = 2 (C = 2, W = 0) L = 758783491, F = 7.58783e+08
TID 1 at work: I = 2, F = 7.58783e+08
-->> TID 0, I = 3 (C = 2, W = 1)
-CW- TID 0, I = 3 (C = 2, W = 1)
-->> TID 2, I = 3 (C = 2, W = 2)
-CW- TID 2, I = 3 (C = 2, W = 2)
-->> TID 1, I = 3 (C = 2, W = 3)
---- TID 1, I = 3 (C = 2, W = 3)
---- TID 1 generates cycle 3: L = 959030623, F = 9.59031e+08
<<-- TID 1, I = 3 (C = 3, W = 0) L = 959030623, F = 9.59031e+08
TID 1 at work: I = 3, F = 9.59031e+08
-->> TID 1, I = 4 (C = 3, W = 1)
-CW- TID 1, I = 4 (C = 3, W = 1)
---- TID 0, I = 3 (C = 3, W = 1)
<<-- TID 0, I = 3 (C = 3, W = 1) L = 959030623, F = 9.59031e+08
TID 0 at work: I = 3, F = 9.59031e+08
---- TID 2, I = 3 (C = 3, W = 1)
<<-- TID 2, I = 3 (C = 3, W = 1) L = 959030623, F = 9.59031e+08
TID 2 at work: I = 3, F = 9.59031e+08
-->> TID 0, I = 4 (C = 3, W = 2)
-CW- TID 0, I = 4 (C = 3, W = 2)
-->> TID 2, I = 4 (C = 3, W = 3)
---- TID 2, I = 4 (C = 3, W = 3)
---- TID 2 generates cycle 4: L = 684387517, F = 6.84388e+08
<<-- TID 2, I = 4 (C = 4, W = 0) L = 684387517, F = 6.84388e+08
TID 2 at work: I = 4, F = 6.84388e+08
---- TID 1, I = 4 (C = 4, W = 0)
<<-- TID 1, I = 4 (C = 4, W = 0) L = 684387517, F = 6.84388e+08
TID 1 at work: I = 4, F = 6.84388e+08
---- TID 0, I = 4 (C = 4, W = 0)
<<-- TID 0, I = 4 (C = 4, W = 0) L = 684387517, F = 6.84388e+08
TID 0 at work: I = 4, F = 6.84388e+08
TID 0 returned 0x0
TID 1 returned 0x0
TID 2 returned 0x0
pthread_once()
pthread_once()
称呼。这不是真正需要的,但
pthread_once()
.
#include <pthread.h>
#include <stdlib.h>
static pthread_once_t once_only = PTHREAD_ONCE_INIT;
static float gl_rand = 0;
static void pt_once(void)
{
gl_rand = (float)lrand48();
}
void *thread_function(void *vp)
{
pthread_once(&once_only, pt_once);
…rest of the code…
return 0;
}
关于c - POSIX 线程,独特的执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42822480/
是否有详细说明从一个 POSIX 版本更改为另一个版本的文档?我正在寻找一些东西,在表格 View 中,详细说明从 2004 年到 2008 年的变化 最佳答案 有点。这是Rationale ,每卷一
根据POSIX FAQ ,该标准已于 2013 年由 IEEE 修订和批准。 与 2008 年的先前标准相比有何变化? 最佳答案 根据 online edition 中的摘要, POSIX.1-2
我正在开发一个简单的并行应用程序,我想在其中使用单个进程来维护有关一系列工作进程的状态信息。设置一个 POSIX 消息队列似乎相对容易,其中所有工蜂都可以向状态维护者发送定期更新。我的问题? POSI
计划使用 posix 信号量来同步 2 个进程。不太确定使用哪个 - 命名或未命名。 各自的优缺点是什么?我如何决定使用哪个?在哪些情况下,一种优于另一种? 谢谢。 最佳答案 如果这两个进程不相关,则
嵌套参数替换在 Zsh 中有效: $ param=abc # nested remove prefix ${...#a} and remove suffix ${...%c} => $ printf
更新:整个问题出在一条错误线上,这是我的 C++ 代码中的语法错误。 在 Linux 上我发现 #define _NSIG 64 在 asm-generic/signal.h ,
我在网上遇到了两个 POSIX 文档。 http://pubs.opengroup.org/onlinepubs/009695399/ (IEEE 标准 1003.1,2004 年版) Abstrac
我正在开发一个简单的软件来检查我是否能够使用我研究过的 POSIX 定时器和信号进行编程。 我正在尝试做一个简单的程序来启动计时器并在一定的纳秒内发出信号 下面的程序运行得不好,所以我写了一些关于我的
如果我有一个通过 shell 运行的应用程序,是否有 POSIX 文档说 --help需要支持吗?我会这么认为,因为这似乎是最流行的终端应用程序(GNU 工具等)中的标准做法。 我很好奇我是否可以使用
自适应 AUTOSAR 基于什么 POSIX PSE51? 在学习自适应 AUTOSAR 时,我发现“自适应 AUTOSAR 基于 POSIX PSE51”。 但是,我不明白什么是 POSIX PSE
GNU bash manual说到shell参数有以下一段话: The command builtin does not prevent builtins that take assignment s
我应该在我的嵌入式 Linux 环境中使用 System V 消息队列还是 Posix 消息队列?项目中常用什么? 最佳答案 两者都有相同的基本工具——信号量、共享内存和消息队列。它们为这些工具提供了
用 tsearch 填充了 POSIX 二叉树后,如何清理整棵树? GCC 提供了 tdestroy 作为扩展,但是如果你想使用 POSIX-only 函数,你该怎么做呢? 我当前的实现使用 twal
来自 C++ 应用程序。为 AIX、HP-UX、Linux、OSX 和 Solaris 编译是否有一种简单的方法来确定应用程序是否可用。在系统启动后 5 分钟内运行? 在 Windows 上我可以这样
System V IPC 和 POSIX IPC 之间有什么区别? 为什么我们有两个标准? 如何决定使用哪些 IPC 函数? 最佳答案 两者都有相同的基本工具——信号量、共享内存和消息队列。它们提供的
根据this ,POSIX 库不包含 getopt.h。但是,我在 unistd.h 中找到了这个: #ifdef __USE_POSIX2 /* Get definitions and proto
我正在尝试使用 POSIX 共享内存和 POSIX 信号量构建客户端服务器应用程序。我是否必须将信号量放在共享内存段内,或者信号量是否可以只是全局变量?我希望遵守 POSIX 约定。 最佳答案 不,信
尝试读取 Rust fn 中任意用户的主目录,并使用 posix::pwd crate。 不幸的是,我找不到任何使用 FFI 的好例子,并且一直在处理关于指针和类型可变性的各种类型错误。 我的(非编译
我阅读了一个信号的手册页使用 man 7 signal我看到两种类型的信号。所以,我有一个问题, Linux 中的POSIX 可靠信号 和POSIX 实时信号 有什么区别? 最佳答案 如今,将这些表述
据我所知,ucontext 提供了比 setjmp 更好的东西。但它已被弃用,现在已从 POSIX 规范中删除。那么它为什么会出现,又为什么会被移除? 最佳答案 makecontext的签名来自 uc
我是一名优秀的程序员,十分优秀!