Pthreads(POSIX Threads)是一个标准化的基于C的API,用于创建和操作线程。它目前由POSIX.1-2008(IEEE Std 1003.1,2013 Edition / The Open Group Base Specifications Issue 7)定义。
我可以通过转到 /proc/$(pidof task)/ 并给出来查看应用程序中使用的线程数 猫的状态。 有没有办法使用命令检查Linux中各个线程的优先级? 重新...
我试图创建三个线程,每个线程打开一个不同的输入文件,从中读取单个字符并将其设置为全局变量,然后等待下一个线程读取单个字符...
如果等待时间为0,是否定义了sem_timedwait,或者在这种情况下我应该调用sem_trywait吗?文档不清楚,源代码仅显示实现。
我有以下代码,它基本上创建两个线程,一个读取一个字符,另一个键入它直到传递字母 f : 字符c; int att = 1; 无效* th_read(无效*k){ ...
为什么pthread_join()的第二个参数是一个**,一个指向指针的指针?
我对使用 pthread 很陌生,而且对指向指针的指针也不太熟悉。有人可以解释为什么 pthread_join() 的第二个参数是 void ** 吗?为什么要这样设计呢。 ...
我正在尝试使用 cmake 安装 plexe-sumo。我按照 plexe.car2x.org 上的教程进行操作,结果如下: -- CMAKE_BUILD_TYPE:发布 -- CMAKE_BINARY_DIR: /home/cc/src/plexe-sumo/build-rele...
我对 C 中的多线程还很陌生。我编写了一个简单的程序,它执行以下操作: main 函数启动多个线程,每个线程等待使用 con...
我正在使用 dbus-cxx 库在使用 DBUS 的程序之间进行通信。然而,我感到困惑的一部分是如何在服务器上打开连接时保持主线程不退出
使用 nix::sys::signal::{self, SigSet}; #[东京::测试] 异步 fn test_shutdown() { 让服务器 = TestServer::new().await; 让 proxy = ProxyUnderTest::new(server.listen_port).await; 睡眠(标准::时间::
我正在尝试用信号量来实现生产者和消费者问题。我认为我的逻辑是正确的,但我的代码没有按预期工作。 #包括 #包括 我正在尝试用信号量来实现生产者和消费者问题。我认为我的逻辑是正确的,但我的代码没有按预期工作。 #include <stdio.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <stdlib.h> #define BUFFER_SIZE 10 int arr[BUFFER_SIZE]; int position; sem_t *mutex, *empty, *filled; void* producer(void* args){ printf("Prod starting\n"); int a,b; sem_getvalue(empty, &a); sem_getvalue(mutex, &b); printf("empty : %d mutex : %d\n", a, b); do{ sem_wait(empty); sem_wait(mutex); int new = rand()%2000; printf("Adding %d to buffer\n", new); arr[position] = new; position++; sem_post(mutex); sem_post(filled); }while(1); } void* consumer(void* arg){printf("Consumer starting\n"); do{ sem_wait(filled); sem_wait(mutex); position--; printf("Consuming %d from buffer", arr[position]); arr[position] = 0; sem_post(mutex); sem_post(empty); }while(1); } int main() { mutex = sem_open("mutex", O_CREAT, 0644, 1); empty = sem_open("empty", O_CREAT, 0644, BUFFER_SIZE); filled = sem_open("filled", O_CREAT, 0644, 0); pthread_t prod, cons; int a, b,c; sem_getvalue(empty, &a); sem_getvalue(filled, &b); sem_getvalue(mutex, &c); printf("empty:%d filled:%d mutex:%d\n", a,b,c); //printf("Producer = %ld Consumer = %ld\n", prod, cons); pthread_create(&prod,NULL,producer,NULL); pthread_create(&cons,NULL,consumer,NULL); pthread_join(prod,NULL); pthread_join(cons,NULL); sem_close(mutex); sem_unlink("mutex"); sem_close(empty); sem_unlink("empty"); sem_close(filled); sem_unlink("filled"); return 0; } 信号量未正确初始化,从以下输出可知: empty:0 filled:0 mutex:0 Prod starting empty : 0 mutex : 0 Consumer starting 我不明白为什么信号量没有正确初始化。从手册页: sem_t *sem_open(const char *name, int oflag, mode_t 模式, unsigned int 值); 如果在 oflag 中指定了 O_CREAT,则需要两个附加参数 必须提供。 mode 参数指定权限 被放置在新的信号量上,该值 参数指定新信号量的初始值。 注意:我不能使用 sem_init,因为最终代码需要在 Macos 上完成。我只是用 sem_getvalue() 在 Linux 上重新创建这个来了解问题。 根据@pilcrow的建议,我将问题重新创建为: #include <stdio.h> #include <pthread.h> #include <semaphore.h> sem_t *mutex; void* thread(void* arg){ printf("Entered thread\n"); sem_wait(mutex); printf("Hello\n"); sem_post(mutex); pthread_exit(NULL); } int main() { mutex = sem_open("mutex", O_CREAT, 0644, 1); if(mutex == SEM_FAILED){ printf("Failed to create semaphore\n"); return 1; } pthread_t id; pthread_create(&id,NULL,thread,NULL); pthread_join(id,NULL); return 0; } 输出: Entered thread 线程继续无限期地等待 mutex 信号量,而该信号量再次未正确初始化。 命名信号量由 /somename 形式的名称标识;也就是说,最多为 NAME_MAX-4 的以空结尾的字符串 (即 251)个字符,由一个初始斜杠组成,后跟一个或多个字符,其中没有一个是斜杠。二 通过将相同的名称传递给 sem_open(3),进程可以对同一个命名的信号量进行操作。 sem_open(3)函数创建一个新的命名信号量或打开一个现有的命名信号量。信号量被设置后 打开后,可以使用sem_post(3)和sem_wait(3)进行操作。当进程使用完信号量后,它可以 使用 sem_close(3) 关闭信号量。当所有进程都使用完该信号量后,可以将其从 系统使用 sem_unlink(3). 多个进程可以打开同一个信号量,这意味着它必须存在于进程范围之外的某个地方 它需要手动取消链接,这表明即使每个打开它的进程都调用了sem_close(),它仍然存在(否则当引用计数变为零时它可能会被销毁)。 在 Linux 上的 strace 下运行测试过程表明信号量由文件 /dev/shm/sem/mutex 支持。其他平台可能有不同的支持位置,但必须支持相同的语义。 需要手动取消链接信号量的明显推论是,如果您不,那么每次您使用相同的名称打开它时都会得到相同的信号量,其中包含先前运行的最后一个值。 如果您确实只想在单个进程中使用信号量并且不能使用未命名的信号量(使用 sem_init()),那么您应该确保名称是唯一的。从 PID 形成一个字符串将是一个好的开始,退出时取消链接也是如此。
我有一个程序,可以从文本文件中读取单词,并计算唯一单词的数量及其频率,可能使用多个线程: #include“向量.h” #定义 MIN_STRING_LEN...
我有一个函数可以在 C 中维护一个动态大小的数组。该程序读取一个文本文件并创建每个唯一单词的列表以及该单词的频率。它有一个搜索功能,看起来...
为了测试错误恢复,我想让 pthread_create 以可预测的方式失败。最明显的方法是对允许的线程数设置硬性上限
我从 https://computing.llnl.gov/tutorials/pthreads/ 获得了一些代码,我尝试使用 VSCode 调试器来尝试单步调试它们,但它似乎不起作用。 使用任务 (ctrl+shift+B) ...
我从 main() 创建了超过 100 个线程,所以我只是想知道在退出 main() 之前是否需要调用 pthread_join() 。 另外,我不需要这些线程生成的数据,基本...
如何制作timer_create和timer_delete多线程证明
我陷入了一种特殊的情况,我从一个线程调用timer_create并从另一个线程调用timer_delete。但我似乎无法让它工作,因为它最终陷入僵局: 我想不通...
我正在使用 pthreads 开发多线程 C 应用程序。我有一个线程写入数据库(数据库库只能安全地在单个线程中使用),还有几个线程......
pthread_join 函数的文档说: 未能加入可加入的线程(即, 未分离),产生“僵尸线程”。 据我了解...
我是 C 新手,想稍微玩一下线程。我想使用 pthread_exit() 从线程返回一些值 我的代码如下: #包括 #包括 我是 C 新手,想稍微玩一下线程。我想使用 pthread_exit() 从线程返回一些值 我的代码如下: #include <pthread.h> #include <stdio.h> void *myThread() { int ret = 42; pthread_exit(&ret); } int main() { pthread_t tid; void *status; pthread_create(&tid, NULL, myThread, NULL); pthread_join(tid, &status); printf("%d\n",*(int*)status); return 0; } 我期望程序输出"42\n",但它输出一个随机数。如何打印返回值? 我返回指向局部变量的指针似乎是一个问题。返回/存储多线程变量的最佳实践是什么?全局哈希表? 这是正确的解决方案。在这种情况下,tdata是在主线程中分配的,并且有一个空间供线程放置其结果。 #include <pthread.h> #include <stdio.h> typedef struct thread_data { int a; int b; int result; } thread_data; void *myThread(void *arg) { thread_data *tdata=(thread_data *)arg; int a=tdata->a; int b=tdata->b; int result=a+b; tdata->result=result; pthread_exit(NULL); } int main() { pthread_t tid; thread_data tdata; tdata.a=10; tdata.b=32; pthread_create(&tid, NULL, myThread, (void *)&tdata); pthread_join(tid, NULL); printf("%d + %d = %d\n", tdata.a, tdata.b, tdata.result); return 0; } 您返回的是局部变量的地址,当线程函数退出时该变量不再存在。无论如何,为什么要打电话给pthread_exit?为什么不简单地从线程函数返回一个值? void *myThread() { return (void *) 42; } 然后在main中: printf("%d\n", (int)status); 如果您需要返回一个复杂的值(例如结构),最简单的方法可能是通过 malloc() 动态分配它并返回指针。当然,启动线程的代码将负责释放内存。 您已返回一个指向局部变量的指针。即使不涉及线程,这也很糟糕。 当启动的线程与加入的线程相同时,通常的方法是将一个指向 int 的指针传递给调用者管理的位置,作为 pthread_create 的第四个参数。然后,这将成为线程入口点的(唯一)参数。您可以(如果您愿意)使用线程退出值来指示成功: #include <pthread.h> #include <stdio.h> int something_worked(void) { /* thread operation might fail, so here's a silly example */ void *p = malloc(10); free(p); return p ? 1 : 0; } void *myThread(void *result) { if (something_worked()) { *((int*)result) = 42; pthread_exit(result); } else { pthread_exit(0); } } int main() { pthread_t tid; void *status = 0; int result; pthread_create(&tid, NULL, myThread, &result); pthread_join(tid, &status); if (status != 0) { printf("%d\n",result); } else { printf("thread failed\n"); } return 0; } 如果您绝对必须使用结构的线程退出值,那么您必须动态分配它(并确保加入线程的人释放它)。但这并不理想。 我认为你必须将数字存储在堆上。 int ret变量位于堆栈上,并在函数myThread执行结束时被销毁。 void *myThread() { int *ret = malloc(sizeof(int)); if (ret == NULL) { // ... } *ret = 42; pthread_exit(ret); } 不需要的时候不要忘记free它 另一种解决方案是将数字作为指针的值返回,就像 Neil Butterworth 所建议的那样。 #include<stdio.h> #include<pthread.h> void* myprint(void *x) { int k = *((int *)x); printf("\n Thread created.. value of k [%d]\n", k); //k =11; pthread_exit((void *)k); } int main() { pthread_t th1; int x =5; int *y; pthread_create(&th1, NULL, myprint, (void*)&x); pthread_join(th1, (void*)&y); printf("\n Exit value is [%d]\n", y); } 您正在返回对 ret 的引用,它是堆栈上的变量。 问题:返回/存储多线程变量的最佳实践是什么?全局哈希表? 这完全取决于您想要返回的内容以及您将如何使用它?如果您只想返回线程的状态(例如线程是否完成了其打算执行的操作),则只需使用 pthread_exit 或使用 return 语句从线程函数返回值。 但是,如果您想要更多信息用于进一步处理,那么您可以使用全局数据结构。但是,在这种情况下,您需要使用适当的同步原语来处理并发问题。或者,您可以分配一些动态内存(最好是用于要存储数据的结构)并通过 pthread_exit 发送它,一旦线程加入,您就可以在另一个全局结构中更新它。这样,只有一个主线程会更新全局结构,并发问题就解决了。但是,您需要确保释放不同线程分配的所有内存。 #include <pthread.h> #include <stdio.h> #include <stdint.h> void *myThread(void *args) { return (void *)(intptr_t)42; } int main(void) { pthread_t tid; void *status; int ret; pthread_create(&tid, NULL, myThread, NULL); ret = pthread_join(tid, &status); if (ret) { fprintf(stderr, "pthread_join() failed\n"); return -1; } /* pthread_join() copies the exit status (namely 42) of the target thread * into the location pointed to by retval (namely &status), &status points * to void *, so we need to cast void * to int. */ printf("%ld\n", (intptr_t)status); return 0; } 如果您对返回地址感到不舒服并且只有一个变量,例如。要返回一个整数值,您甚至可以在传递它之前将其类型转换为 (void *),然后当您在 main 中收集它时,再次将其类型转换为 (int)。您拥有价值,而不会发出丑陋的警告。 我这样做了: void *myThread() { int ret = 42; return (void*)(__intptr_t)ret; } int main() { pthread_t tid; int status = 1; pthread_create(&tid, NULL, myThread, NULL); pthread_join(tid, (void*)(__intptr_t)&status); printf("%d\n",status); return 0; }
我的问题很奇怪,但就是这样。我的问题:是否有任何解释为什么 posix 线程开发人员无法从分离的线程获取退出代码? 我明白了...