C pthread_创建并传递一个整数作为最后一个参数
我有以下职能:C pthread_创建并传递一个整数作为最后一个参数,c,pthreads,C,Pthreads,我有以下职能: void *foo(void *i) { int a = (int) i; } int main() { pthread_t thread; int i; pthread_create(&thread, 0, foo, (void *) i); } 在编译时,关于强制转换((void*)i和int a=(int)i)有一些错误。如何正确地传递整数作为pthread\u create的最后一个参数?您可以在堆上分配int,并将其传递给pt
void *foo(void *i) {
int a = (int) i;
}
int main() {
pthread_t thread;
int i;
pthread_create(&thread, 0, foo, (void *) i);
}
在编译时,关于强制转换(
(void*)i
和int a=(int)i
)有一些错误。如何正确地传递整数作为pthread\u create
的最后一个参数?您可以在堆上分配int
,并将其传递给pthread\u create()
。然后,您可以在线程函数中取消分配它:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
int *i = malloc(sizeof(*i));
pthread_create(&thread, 0, foo, (void *) i);
}
您应该在pthread_create()的最后一个参数中强制转换
i
的地址(而不是像现在这样转换i
的值)
而且你的演技也是错误的。应该是:
int a = *((int*) i);
i
初始化为某个值,因为它现在未初始化int main(int argc,char*argv[])
或其等效项。基于szx的答案(因此请给他评分),以下是它在for
循环中的工作方式:
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main() {
pthread_t thread;
for ( int i = 0; i < 10; ++1 ) {
int *arg = malloc(sizeof(*arg));
if ( arg == NULL ) {
fprintf(stderr, "Couldn't allocate memory for thread arg.\n");
exit(EXIT_FAILURE);
}
*arg = i;
pthread_create(&thread, 0, foo, arg);
}
/* Wait for threads, etc */
return 0;
}
void*foo(void*i){
int a=*((int*)i);
免费(i);
}
int main(){
pthread\u t线程;
对于(int i=0;i<10;++1){
int*arg=malloc(sizeof(*arg));
如果(arg==NULL){
fprintf(stderr,“无法为线程arg分配内存。\n”);
退出(退出失败);
}
*arg=i;
pthread_创建(&thread,0,foo,arg);
}
/*等待线程等*/
返回0;
}
在循环的每次迭代中,您都在分配新内存,每个内存都有不同的地址,因此在每次迭代中传递给
pthread\u create()
的内容是不同的,因此,没有一个线程会尝试访问相同的内存,并且不会像传递i
的地址那样出现任何线程安全问题。在本例中,您还可以设置一个数组并传递元素的地址。这是一个老问题,但我今天遇到了同样的问题,我决定不走这条路。
我的应用程序实际上是关于性能的,所以我选择静态声明int
s数组
由于我不知道有多少应用程序的pthread\u join
/pthread\u cancel
位于pthread\u create
之外的另一个范围内,因此我选择了以下方式:
#define NB_THREADS 4
void *job(void *_i) {
unsigned int i = *((unsigned int *) _i);
}
int main () {
unsigned int ints[NB_THREADS];
pthread_t threads[NB_THREADS];
for (unsigned int i = 0; i < NB_THREADS; ++i) {
ints[i] = i;
pthread_create(&threads[i], NULL, job, &ints[i]);
}
}
#定义NBU线程4
void*作业(void*\u i){
无符号整数i=*((无符号整数*)\u i);
}
int main(){
无符号整数[NB_线程];
pthread_t threads[NB_threads];
for(无符号整数i=0;i
我发现它更优雅、更高效,而且您不必担心释放,因为它只存在于此范围内。虽然这是一个老问题,但当您只需要像描述符一样传递正整数时,缺少一个选项:您可以直接将其作为地址传递,虽然它是一个黑客,但它工作良好,避免分配任何东西:) 注意:整数的大小必须与操作系统上指针的大小相匹配,但现在大多数系统都是64位本机系统
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
void *_thread_loop(void *p)
{
uint64_t n = (uint64_t)p;
printf("received %llu\n", n);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t read_thread_id;
uint64_t n = 42;
pthread_create(&read_thread_id, NULL, _thread_loop, (void *)n);
pthread_join(read_thread_id, NULL);
return 0;
}
#包括
#包括
#包括
void*\u线程\u循环(void*p)
{
uint64_t n=(uint64_t)p;
printf(“收到%llu\n”,n);
返回NULL;
}
int main(int argc,char const*argv[]
{
pthread_t read_thread_id;
uint64_t n=42;
pthread_create(&read_thread_id,NULL,_thread_loop,(void*)n);
pthread_join(read_thread_id,NULL);
返回0;
}
如果在for
循环中声明了i
,这是否有效?例如,For(inti=0;…)
或者我应该在For
循环之前声明它吗?在For循环中声明也一样&它的工作方式是相同的。但只有在C99(或更高版本)模式下才允许在for循环中声明变量。例如,您需要使用-std=c99
以及其他编译器选项进行编译。此外,如果我使用&I
,那么我将为线程提供变量I
的地址。如果我创建了其他线程,I
不会在所有线程之间共享吗?这不是我们想要的行为。我不确定第二种解决方案是否有效。当第一个线程到达inta=*((int*)i)
时,for循环可能已经更改了i
的值。因此,当第一个线程尝试初始化a
时,它将无法读取正确的值。@Gradient:您是正确的,传递循环变量的地址不能保证安全。将int
强制转换为指针并返回的结果由实现定义,因此这也不是一个很好的解决方案。使用malloc()
是最好的方法。正如我在另一个答案中所说:我不确定这个解决方案是否有效。当第一个线程到达inta=*((int*)i)
时,for循环可能已经更改了i
的值。因此,当第一个线程尝试初始化a
时,它不会读取正确的值。或者我对线程的概念感到困惑?@Gradient:你的另一个评论是正确的,但这里并不是这样。此解决方案为每个线程分配参数的新内存(或者,至少,如果将其放入循环中,则会在每个循环中分配新内存),因此每个线程都会获得一个不同的对象,并且没有两个线程尝试访问同一内存。你对线程的概念理解正确,这个解决方案没有表现出你提到的问题。我认为,通过实际展示它在循环中的工作方式,这个解决方案将会得到改进。我在编译时得到了这一点:error:invalid conversion from'void*'to'int*'
在这一行:int*arg=malloc(sizeof(*arg))代码>。你应该在MaloC之前放置(int *)。@渐变:你必须编译为C++。在C语言中,强制转换是不必要的,在我看来,不应该包括在内代码>应改为int*arg=
#define NB_THREADS 4
void *job(void *_i) {
unsigned int i = *((unsigned int *) _i);
}
int main () {
unsigned int ints[NB_THREADS];
pthread_t threads[NB_THREADS];
for (unsigned int i = 0; i < NB_THREADS; ++i) {
ints[i] = i;
pthread_create(&threads[i], NULL, job, &ints[i]);
}
}
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
void *_thread_loop(void *p)
{
uint64_t n = (uint64_t)p;
printf("received %llu\n", n);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_t read_thread_id;
uint64_t n = 42;
pthread_create(&read_thread_id, NULL, _thread_loop, (void *)n);
pthread_join(read_thread_id, NULL);
return 0;
}