pthreads 相关问题

Pthreads(POSIX Threads)是一个标准化的基于C的API,用于创建和操作线程。它目前由POSIX.1-2008(IEEE Std 1003.1,2013 Edition / The Open Group Base Specifications Issue 7)定义。

使用条件变量输出 Mandelbrot 的线程同步问题

我尝试将线程与条件变量同步以输出曼德尔博特,但我得到了错误的曼德尔博特。 函数output_mandel_line 和compute_mandel_line 已给出并且是正确的。我做了...

回答 1 投票 0

Linux 上使用默认 (SCHED_OTHER) 调度策略的每线程调度优先级

我正在尝试实现一个跨平台包装器来调整当前线程优先级;在 POSIX 上,“正确”的事情看起来像 /// 设置当前t的优先级调整...

回答 1 投票 0

涉及 pthreads 的最琐碎的 C 程序中出现奇怪的零星错误

下面是一个简单程序的 C 源代码。 该程序有一个主循环,要求用户在 3 个选项之间进行选择: 1-打印一些文本 2-做一些工作(没有副作用) 3-退出...

回答 1 投票 0

为什么CPU_SET采用整数而不是无符号整数作为第一个参数?

我知道有 CPU_SET(int cpu, cpu_set_t *set) 用于设置核心关联性。根据该函数的签名,我们还可以将负数作为 cpu_id 传递给 CPU 组。你能请...

回答 1 投票 0

为什么我们使用线程并一起选择[重复]

我正在使用c中的套接字编程与一些客户端设置服务器。 我发现为了拥有多个客户端,我应该使用线程或选择或轮询。 我知道我应该如何使用这些

回答 1 投票 0

pthread和select()函数的用途是什么?

我们的教授在课堂上给了我们这个代码: st = select(max+1, &rs, NULL, NULL, &timeinterval); 如果(st){ for(int i=0; i 我们的教授在课堂上给了我们这个代码: st = select(max+1, &rs, NULL, NULL, &timeinterval); if(st){ for(int i=0; i<workers; i++) { if(FD_ISSET(channels[i]->read_fd(), &rs)) 老实说,我很难理解它在做什么。我尝试研究更多有关 pthreads 的信息,但似乎没有任何内容可以解释它的作用。他说这与文件描述符有关,但我不明白这段代码是如何发生的。 这个select的目的是等待多个文件描述符,可能会超时,当它返回一个正数时,这意味着rs集中至少有一个fd准备好读取,这样在一个循环,检查它是哪个 fd,并对其执行读取。 注意,您应该检查大于 0 的值,因为如果出现错误,将返回 -1,您不应该检查 fd_set 而是处理错误: if(st > 0) { for(int i=0; i<workers; i++) { if(FD_ISSET(channels[i]->read_fd(), &rs)) { // perform read on channels[i]->read_fd } } } else if (st == 0) { // handle time out } else { // handle error } 我使用选择功能为短定时器创建延迟。我想知道 usleep(x) 或 sleep(x) 是否比这个更好,尽管这可能更精确: void delay(double time) { if ( time<0.000001) { return; } int uSec =static_cast<int>(time*1000.0f); struct timeval tv; tv.tv_usec =(__suseconds_t)uSec; tv.tv_sec = (time_t)(uSec / 1000000); select(0, NULL, NULL, NULL, &tv); }

回答 2 投票 0

线程障碍。线程 T6.13 只能在 6 个线程(包括其自身)运行时结束

• 进程的主线程,即 T6.0 不得在其他 43 个线程之前终止。 • 任何时候,进程P6最多可以有6个线程同时运行,不包括主线程。 我的代码

回答 1 投票 0

如果信号量上有服务员,为什么线程可以向自身发送消息?

这是我为理解信号量语义而编写的一些代码: #包括 #包括 #包括 #包括 #包括 这是我为理解信号量语义而编写的一些代码: #include <semaphore.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> sem_t sem; void *helper(void *arg) { sem_wait(&sem); printf("helper woke up\n"); } int main() { sem_init(&sem, 0, 0); pthread_t tid; pthread_create(&tid, NULL, helper, NULL); sleep(1); sem_post(&sem); sem_wait(&sem); printf("main woke up\n"); exit(0); } 为什么打印这个 main woke up 而不是这个? helper woke up 如果我们查看手册页,就会发现 如果信号量的值因此变得大于零,那么 在 sem_wait(3) 调用中阻塞的其他进程或线程将被唤醒并继续锁定信号量。 那么为什么允许主线程而不是辅助线程继续进行呢? 我在 Linux 上尝试了这段代码,得到了和你一样的结果。 但是当我使用gdb一步步调试这段代码时,我发现终端上打印了helper woke up,然后主线程将永远等待。 所以我认为这可能是一个未定义的行为,因为主线程永远不会进入 printf 函数,并且 main 函数永远不会退出。所以可能会涉及到一些奇怪的系统机制。 你可以删除主函数中最后一个sem_wait(&sem);,就会得到这样的结果。 helper woke up main woke up

回答 1 投票 0

为线程设置新优先级时不允许操作

我创建了两个线程。默认情况下,它们的优先级为 0,我可以使用 pthread_getschedparam 然后我尝试分别增加它们的优先级为 2 和 3。但是当我尝试...

回答 4 投票 0

std::thread 与 c++ 11 的 pthread_setschedparam

我想设置开发的自定义线程池的优先级。所以我发现要设置优先级需要使用pthred的pthread_setschedparam方法。由于 pthread_t 和 native_handle_type 不同...

回答 1 投票 0

select 未指示 pthread_create 启动的函数中数据到达

我编写了一个简单的多线程 TCP 回显服务器来试验线程。下面是我的主要功能的代码。 #include“server_lib.h” #包括 #包括 我编写了一个简单的多线程 TCP 回显服务器来试验线程。下面是我的主要功能的代码。 #include "server_lib.h" #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <errno.h> int main(int argc, char *argv[]) { Server s = setup_socket(); pthread_t clients[MAX_CLIENT]; int connfd, rv = 0; client_data.client_number = 0; for(;;) { connfd = accept(s.sockfd, (struct sockaddr*)&s.sa, (socklen_t*)&s.addrlen); if (connfd < 0 && errno != EAGAIN) handle_error("accept failed"); if (connfd > 0) { client_data.client_number++; if (client_data.client_number <= MAX_CLIENT) { socket_nonblocking(&connfd); disable_nagles_algo(&connfd); /* Send the client number to client first */ rv = send(connfd, (void *)&client_data.client_number, sizeof(client_data.client_number), 0); ThreadDataT *t = (ThreadDataT*)malloc(sizeof(ThreadDataT)); t->fd = connfd; if (pthread_create(&clients[client_data.client_number-1], NULL, HandleMessage, (void*)t) != 0){ handle_error("pthread_create failed"); } /* Lets close our copy of connfd */ } else { rv = send(connfd, "Max clients reached!\n", 21, 0); client_data.client_number--; close(connfd); } } usleep(100000); } close(s.sockfd); } 这是通过 pthread_create 调用的 HandleMessage 函数的代码。 void* HandleMessage(void *data) { /* Lets detach first */ pthread_detach(pthread_self()); struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0; ThreadDataT *t = (ThreadDataT*)data; fd_set testfd; FD_ZERO(&testfd); FD_SET(t->fd, &testfd); int rv = 0; for (;;) { int result = select(FD_SETSIZE, &testfd, NULL, NULL, &timeout); if (result < 0) { perror("select failed"); pthread_exit(&result); } if (result > 0) { if(FD_ISSET(t->fd, &testfd)) { /* We have some data */ rv = echo_content(&t->fd); if (rv < 0) { if (rv != -10) perror("echo_content failed"); close(t->fd); free(t); pthread_exit(NULL); } } } usleep(1000); } return 0; } 下面是评论中要求的 echo_content 函数的代码。 int echo_content(int *connfd) { unsigned char buffer[2048]; int size = recv(*connfd, buffer, sizeof(buffer), 0); if (size < 0) handle_error("recv"); if (size > 0) { if (strstr((const char*)buffer, "quit") != NULL){ printf("Closing connection with client\n"); send(*connfd, "bye\n", 4, 0); return -10; } size = send(*connfd, buffer, size, 0); } else printf("WARNING: Failed to recieve data\n"); return size; } 代码使用的数据结构定义如下。 #ifndef __SERVER_LIB_H__ #define __SERVER_LIB_H__ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <sys/select.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <unistd.h> #include <fcntl.h> #include <pthread.h> #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while(0) #define PORT 50000 #define MAX_CLIENT 2 typedef struct { int sockfd; struct sockaddr_in sa; int addrlen; } Server; typedef unsigned char ClientNumber; typedef struct { ClientNumber clients[MAX_CLIENT]; short client_number; } ClientDataT; ClientDataT client_data;; typedef struct { int fd; } ThreadDataT; Server setup_socket(void); int echo_content(int *); void socket_nonblocking(int *); void disable_nagles_algo(int *); void* HandleMessage(void*); #endif /* __SERVER_LIB_H__ */ 编译上面的代码后,我可以使用 telnet 连接到它。我在telnet中没有看到服务器发送的客户端号码。接下来,我输入了一些消息并期待它回显,但那没有发生。 在调试时,我注意到无论我在客户端输入什么,HandleMEssage 中的 select 系统调用总是返回 0。只是为了测试,我然后设置 select 的 writefds 参数,然后 select 返回值 > 0 并指示套接字期望被写入。相同的代码适用于 fork 模型。 (基于分叉的代码是here)。 代码几乎与基于分支的代码类似,所以我有点不明白为什么它不起作用。任何人都可以指出我在这里可能做错了什么吗?. 可能还有其他问题,但尝试将 FD_SET() 移到循环内: for (;;) { FD_SET(t->fd, &testfd); int result = select(FD_SETSIZE, &testfd, NULL, NULL, &timeout); AFIK,select()调用修改fd-sets,并且可能从集合中删除testfd。 另一个可能的问题是 select() 调用的零超时。 select 的手册页说: 如果两个字段 timeval 结构为零,然后 select() 立即返回。 (这 对于轮询很有用。)如果超时为 NULL(无超时),则 select() 可以无限期阻止。 您也可以尝试无限期超时: for (;;) { FD_SET(t->fd, &testfd); int result = select(FD_SETSIZE, &testfd, NULL, NULL, NULL); 这样你就可以消除丑陋的轮询睡眠:usleep(1000);。

回答 1 投票 0

如何中断选择

我正在编写一个程序,我在 while (1) 循环中运行,该循环会阻塞选择调用。我的程序侦听多个客户端连接的服务器套接字。我还连接到不同的服务器...

回答 3 投票 0

pthread_cond_signal 或 pthread_cond_broadcast 调用是否意味着写内存屏障?

条件变量通常用于在互斥锁下修改它们引用的状态。但是,当状态只是一个仅设置标志时,不需要互斥锁来阻止

回答 4 投票 0

R 中的 pthread 支持

我正在寻找一种在后台将 R 函数作为单独线程运行的方法。 由于 R 是用 C 编写的,我希望某些包能够支持使用 pthread 的线程。 到目前为止我已经...

回答 2 投票 0

PHP:pthreads 未在 PHP 8.1 上加载

我正在尝试在 PHP 8.1 TS 上添加 pthreads 扩展,但它似乎不起作用,据说它没有安装,但实际上已经安装了。 PHP-v PHP 8.1.10(cli)(构建:2022 年 8 月 30 日 18:05:49)(ZTS V...

回答 2 投票 0

在 Linux 中,哪个选项更快:发布/解锁信号量/互斥体或创建新线程?

我有一个在 Linux 中运行的应用程序。它有一个用于实时控制的线程,这意味着该线程必须定期运行(周期约为 200 微秒)并且它...

回答 1 投票 0

Pthread条件睡眠?

我正在尝试找到一种简单的方法来睡眠或停止执行,并唤醒 C 中的另一个(而不是调用的)线程。 它应该像这样工作: int 主函数(无效) { int 消息 = 0; ptread_t t;

回答 2 投票 0

C:在线程终止之前从线程打印

我正在使用Boost,但我的一般问题是: 假设我有这种情况: // 线程创建 pthread_create(&thread_ptr, NULL, 运行者, NULL); // 线程加入/杀死 pthread_join(thread_ptr...

回答 1 投票 0

C/C++:在线程终止之前从线程打印

我正在使用Boost,但我的一般问题是: 假设我有这种情况: // 线程创建 pthread_create(&thread_ptr, NULL, 运行者, NULL); // 线程加入/杀死 pthread_join(thread_ptr...

回答 1 投票 0

为什么我的程序大部分时间都在睡眠状态却占用如此多的CPU时间?

我的程序需要一些计时器,我决定用 pthreads 来编写它。 我的计时器需要在每个 update_interval 滴答声中通过更新回调更新一些信息。 我是这样做的: 定时器.h: #我...

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.