Pthreads(POSIX Threads)是一个标准化的基于C的API,用于创建和操作线程。它目前由POSIX.1-2008(IEEE Std 1003.1,2013 Edition / The Open Group Base Specifications Issue 7)定义。
我有一个简单的问题。我应该创建一个小型多线程程序来从多个传感器获取数据,并且我了解 pthreads 和 qthreads。我可以访问这两个图书馆。
我正在使用 C++ 和 pthreads 进行一些事件处理。我有一个从我定义的事件队列中读取的主线程,以及一个填充事件队列的工作线程。队列当然是线程安全的。 ...
线程如何与“pthread_create”时传递的“启动例程”函数一起工作?
我刚刚开始了解线程如何使用 pthreads 库在 Linux (Ubuntu) 上真正工作。我被困在第一个程序上。先看代码: #包括 #包括
在Linux C程序中,如何打印pthread库创建的线程的线程id?例如我们如何通过 getpid() 获取进程的 pid。
我的目标是: 我想让多个线程运行同一个函数,该函数是一个 while(1) 循环,所以它会继续下去。在某些时候,main 应该使用互斥体来强制所有线程阻塞 u...
Windows 上 C 语言的主函数结束后如何保持线程存活?
问题: 我正在开发一个 Windows 的 C 项目,我需要创建一个独立于主函数运行的线程。目标是确保该线程即使在 m...
我尝试将线程与条件变量同步以输出曼德尔博特,但我得到了错误的曼德尔博特。 函数output_mandel_line 和compute_mandel_line 已给出并且是正确的。我做了...
Linux 上使用默认 (SCHED_OTHER) 调度策略的每线程调度优先级
我正在尝试实现一个跨平台包装器来调整当前线程优先级;在 POSIX 上,“正确”的事情看起来像 /// 设置当前t的优先级调整...
涉及 pthreads 的最琐碎的 C 程序中出现奇怪的零星错误
下面是一个简单程序的 C 源代码。 该程序有一个主循环,要求用户在 3 个选项之间进行选择: 1-打印一些文本 2-做一些工作(没有副作用) 3-退出...
为什么CPU_SET采用整数而不是无符号整数作为第一个参数?
我知道有 CPU_SET(int cpu, cpu_set_t *set) 用于设置核心关联性。根据该函数的签名,我们还可以将负数作为 cpu_id 传递给 CPU 组。你能请...
我正在使用c中的套接字编程与一些客户端设置服务器。 我发现为了拥有多个客户端,我应该使用线程或选择或轮询。 我知道我应该如何使用这些
我们的教授在课堂上给了我们这个代码: 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); }
线程障碍。线程 T6.13 只能在 6 个线程(包括其自身)运行时结束
• 进程的主线程,即 T6.0 不得在其他 43 个线程之前终止。 • 任何时候,进程P6最多可以有6个线程同时运行,不包括主线程。 我的代码
这是我为理解信号量语义而编写的一些代码: #包括 #包括 #包括 #包括 #包括 这是我为理解信号量语义而编写的一些代码: #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
我创建了两个线程。默认情况下,它们的优先级为 0,我可以使用 pthread_getschedparam 然后我尝试分别增加它们的优先级为 2 和 3。但是当我尝试...
std::thread 与 c++ 11 的 pthread_setschedparam
我想设置开发的自定义线程池的优先级。所以我发现要设置优先级需要使用pthred的pthread_setschedparam方法。由于 pthread_t 和 native_handle_type 不同...
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);。
我正在编写一个程序,我在 while (1) 循环中运行,该循环会阻塞选择调用。我的程序侦听多个客户端连接的服务器套接字。我还连接到不同的服务器...
pthread_cond_signal 或 pthread_cond_broadcast 调用是否意味着写内存屏障?
条件变量通常用于在互斥锁下修改它们引用的状态。但是,当状态只是一个仅设置标志时,不需要互斥锁来阻止