gpt4 book ai didi

Linux多线程,暂停一个线程,同时继续运行同一进程中的其他线程

转载 作者:太空狗 更新时间:2023-10-29 12:14:01 26 4
gpt4 key购买 nike

我找不到合适的解决方案来解决我的问题。

如果我在一个进程中有多个线程。我只想让一个线程在同一进程中运行其他线程时进入休眠状态,是否有任何预定义的语法,或者我是否必须执行自己的实现( sleep )?

理想情况下,我想在 sleep 时间到来时从一个线程向另一个线程发送一个指示。

已编辑 (2015-08-24)我有两个主线程,一个用于通过网络发送数据,另一个从网络接收数据。除了抖动之外,接收线程还进行验证和验证以及一些文件管理,这可能会及时导致它拖延。我喜欢做的是向发送者添加微 sleep 之类的东西,以便接收者能够 catch 。 sched_yield() 在这种情况下无济于事,因为 HW 具有超过 40 个内核的多核 CPU。

最佳答案

根据您在评论中的描述,您似乎正在尝试同步 2 个线程,以便其中一个线程不会落后于另一个线程太远。

如果是这样,那你就走错了路。通过休眠进行同步很少是一个好主意,因为调度程序可能会导致不可预测的长时间延迟,从而导致其他(慢速)线程在运行队列中保持停止状态而没有被调度。即使它在大部分时间都有效,它仍然是一个竞争条件,而且是一个丑陋的 hack。

鉴于您的用例和限制,我认为您最好使用障碍(参见 pthread_barrier_init(3) )。 Pthread 障碍允许您在代码中创建一个线程可以 catch 的集合点。

你调用pthread_barrier_init(3)作为初始化代码的一部分,指定将使用该屏障同步的线程数。在这种情况下,它是 2。

然后,线程通过调用 pthread_barrier_wait(3) 与其他线程同步.调用阻塞,直到达到 pthread_barrier_init(3) 中指定的线程数为止调用pthread_barrier_wait(3) ,此时在 pthread_barrier_wait(3) 中被阻止的每个线程变得可运行并且循环再次开始。从本质上讲,障碍创造了一个同步点,在每个人都到达之前没有人可以前进。我想这正是您要找的。

这是一个模拟快速发送线程和慢速接收线程的示例。它们都与屏障同步,以确保发送方在接收方仍在处理其他请求时不做任何工作。线程在其工作单元结束时同步,当然,您可以选择每个线程调用 pthread_barrier_wait(3) 的位置。 ,从而准确控制线程同步的时间(和位置)。

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

pthread_barrier_t barrier;

void *sender_thr(void *arg) {
printf("Entered sender thread\n");

int i;
for (i = 0; i < 10; i++) {
/* Simulate some work (500 ms) */
if (usleep(500000) < 0) {
perror("usleep(3) error");
}

printf("Sender thread synchronizing.\n");
/* Wait for receiver to catch up */
int barrier_res = pthread_barrier_wait(&barrier);
if (barrier_res == PTHREAD_BARRIER_SERIAL_THREAD)
printf("Sender thread was last.\n");
else if (barrier_res == 0)
printf("Sender thread was first.\n");
else
fprintf(stderr, "pthread_barrier_wait(3) error on sender: %s\n", strerror(barrier_res));
}

return NULL;
}

void *receiver_thr(void *arg) {
printf("Entered receiver thread\n");

int i;
for (i = 0; i < 10; i++) {
/* Simulate a lot of work */
if (usleep(2000000) < 0) {
perror("usleep(3) error");
}

printf("Receiver thread synchronizing.\n");
/* Catch up with sender */
int barrier_res = pthread_barrier_wait(&barrier);
if (barrier_res == PTHREAD_BARRIER_SERIAL_THREAD)
printf("Receiver thread was last.\n");
else if (barrier_res == 0)
printf("Receiver thread was first.\n");
else
fprintf(stderr, "pthread_barrier_wait(3) error on receiver: %s\n", strerror(barrier_res));
}

return NULL;
}

int main(void) {
int barrier_res;
if ((barrier_res = pthread_barrier_init(&barrier, NULL, 2)) != 0) {
fprintf(stderr, "pthread_barrier_init(3) error: %s\n", strerror(barrier_res));
exit(EXIT_FAILURE);
}

pthread_t threads[2];

int thread_res;
if ((thread_res = pthread_create(&threads[0], NULL, sender_thr, NULL)) != 0) {
fprintf(stderr, "pthread_create(3) error on sender thread: %s\n", strerror(thread_res));
exit(EXIT_FAILURE);
}
if ((thread_res = pthread_create(&threads[1], NULL, receiver_thr, NULL)) != 0) {
fprintf(stderr, "pthread_create(3) error on receiver thread: %s\n", strerror(thread_res));
exit(EXIT_FAILURE);
}

/* Do some work... */

if ((thread_res = pthread_join(threads[0], NULL)) != 0) {
fprintf(stderr, "pthread_join(3) error on sender thread: %s\n", strerror(thread_res));
exit(EXIT_FAILURE);
}
if ((thread_res = pthread_join(threads[1], NULL)) != 0) {
fprintf(stderr, "pthread_join(3) error on receiver thread: %s\n", strerror(thread_res));
exit(EXIT_FAILURE);
}

if ((barrier_res = pthread_barrier_destroy(&barrier)) != 0) {
fprintf(stderr, "pthread_barrier_destroy(3) error: %s\n", strerror(barrier_res));
exit(EXIT_FAILURE);
}

return 0;
}

请注意,正如 pthread_barrier_wait(3) 的联机帮助页中所指定的那样, 一旦所需的线程数调用 pthread_barrier_wait(3) ,屏障状态重置为上次调用 pthread_barrier_init(3) 后使用的原始状态,这意味着屏障以原子方式解锁和重置状态,因此它始终为下一个同步点做好准备,这非常棒。

完成屏障后,不要忘记使用 pthread_barrier_destroy(3) 释放相关资源.

关于Linux多线程,暂停一个线程,同时继续运行同一进程中的其他线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32097820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com