将参数传递给 pthread_create - 从 void(*)() 到 void(*)(void*) 的无效转换

Posted

技术标签:

【中文标题】将参数传递给 pthread_create - 从 void(*)() 到 void(*)(void*) 的无效转换【英文标题】:Passing arguments to pthread_create - invalid conversion from void(*)() to void(*)(void*) 【发布时间】:2013-11-26 22:14:03 【问题描述】:

我正在编写一个使用 pthreads 实现循环执行计划的简单小程序。我首先编写了没有 pthreads 的程序,现在正试图正确地将参数传递给 pthread_create。 我知道参数是:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

但是将线程发送到 ttable(时间表)给我带来了困难。 现在我正在使用线程,即使我没有使用它,我也添加了 void* x 参数(是否需要此参数?)我尝试不使用任何参数并将 NULL 作为 pthread_create 的最后一个参数传入。 我目前的错误是:错误:从'void(*)()'到'void(*)(void*)'的无效转换[-fpermissive] ; ^

代码如下:

#include <ctype.h>
#include <unistd.h>
#include <sys/times.h>
#include <pthread.h>

#define SLOTX   6
#define CYCLEX  4
#define SLOT_T  1000    //1 second slot time
#define NUM_THREADS 3

int tps;
int i;
int j;
int rc;
int cycle = 0;
int slot = 0;
struct tms n;

void one(void* x)
        printf("Task 1 running\n");
        sleep(1);


void two(void* x)
        printf("Task 2 running\n");
        sleep(1);


void three(void* x)
        printf("Task 3 running\n");
        sleep(1);


void burn(void* x)
        printf("Burn cycle\n");
        sleep(1);


void (*ttable[SLOTX][CYCLEX])(void* x) = 
        one,   one,    two,    two,
        three, three,  three,  three,
        two,   two,    one,    one,
        burn,  two,    two,    burn,
        three, three,  three,  three,
        one,   one,    two,    two
;

main()
        tps = sysconf(_SC_CLK_TCK);
        pthread_t thread[NUM_THREADS];
        printf("clock ticks/sec = %d\n\n", tps);
        while(1)
                printf("Starting new hyperperiod\n");
                for(slot = 0; slot<SLOTX; slot++)
                        printf("Starting new frame\n");
                        for(cycle = 0; cycle<CYCLEX; cycle++)
                                for(i = 0; i<NUM_THREADS; i++)
                                        rc = pthread_create(&thread[i], NULL, (*ttable[slot][cycle]), *(void*)j);
                                
                        
                
        


【问题讨论】:

使用 void one(void*) 而不是 void one() 等,否则我认为您需要将 (void *x) 更改为 () 将 (void* x) 更改为 () 使我无法从 void (*)() 转换为 void()(void*) 并更改 void one()/ two()/three() to void one(void*) 给了我从 void()(void) 到 void(*)() 的无效转换 其实我错了——你需要包含一个参数名称,因为它是一个函数定义而不是一个声明。使用 R.. 建议的虚拟参数。 【参考方案1】:

pthread_create 的启动函数必须只采用一个 void * 类型的参数。你的参数为零。修复它们以采用 void * 类型的虚拟参数,一切都应该没问题。

【讨论】:

pthread_create 中的 (void*)i 和 ttable 中的 (void* x) 应该做到这一点吗?如果 ttable 是启动函数? 没有。您实际上必须更改函数 definitions 以获取参数,即使您不想使用它。任何其他尝试的解决方案都会调用未定义的行为(即使它使错误/警告消失并且看起来有效)。 感谢您的帮助——这解决了我的问题,但现在“'void*' 不是指向对象类型的指针”。我已经更新了上面的代码...所以我知道这意味着我有一个指向整数 * (void* )j 的 void 指针...是否可以将整数转换为 void 指针? (如果这是一个愚蠢的问题,我深表歉意……我一直在努力寻找解决此问题的方法/方法,并觉得我正在使它变得比应有的复杂得多)。 哪一行产生了错误?顺便说一句,在对问题中的代码进行更改时,最好添加新内容而不是更改旧内容。随着代码(或其他问题内容)的更改,对于将来阅读它的任何人来说,这个问题都会变得非常混乱...... 谢谢。违规行是 rc = pthread_create(&thread[i], NULL, (* ttable[slot][cycle]), * (void* )j);【参考方案2】:

使用以下内容:

typedef void* (*ThreadFunc_t) (void *);
ThreadFunc_t ttable[SLOTX][CYCLEX] = 
    one,   one,    two,    two,
    three, three,  three,  three,
    two,   two,    one,    one,
    burn,  two,    two,    burn,
    three, three,  three,  three,
    one,   one,    two,    two
;

...

rc = pthread_create(&thread[i], NULL, (ttable[slot][cycle]), (void*)i);

如果你使用 pthread_ctreate,你必须遵循它的接口: int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);

希望对你有帮助!

【讨论】:

以上是关于将参数传递给 pthread_create - 从 void(*)() 到 void(*)(void*) 的无效转换的主要内容,如果未能解决你的问题,请参考以下文章

从后面的代码将参数传递给 URL

如何从反应原生桥将参数传递给swift类

将参数传递给从另一个控制器公开的方法

从 powershell.exe 将参数传递给脚本

从 subprocess.Popen 将参数传递给 argparse

从 android 或 iOS 将参数传递给颤振模块