C-试图将字符传递到pthread_create,出现分段错误
好的,我已经创建了4个pthread(我正在创建4个线程,每个线程将管理一个基本方向,北、南、东或西): 我有我的threadcode函数C-试图将字符传递到pthread_create,出现分段错误,c,multithreading,segmentation-fault,pthreads,C,Multithreading,Segmentation Fault,Pthreads,好的,我已经创建了4个pthread(我正在创建4个线程,每个线程将管理一个基本方向,北、南、东或西): 我有我的threadcode函数 void *threadcode(void* dir) { char* direction; struct cart_t *cart = NULL; direction = (char*)dir; printf("casted direction %c\n", *direction); fprintf(stderr, "thread for direc
void *threadcode(void* dir)
{
char* direction;
struct cart_t *cart = NULL;
direction = (char*)dir;
printf("casted direction %c\n", *direction);
fprintf(stderr, "thread for direction %c starts\n", *direction);
cart = q_getCart(*direction);
while (cart != NULL) {
fprintf(stderr, "thread for direction %c gets cart %i\n",
*direction, cart->num);
monitor_arrive(cart);
monitor_cross(cart);
monitor_leave(cart);
cart = q_getCart(*direction);
}
fprintf(stderr, "thread for direction %c exits\n", *direction);
return NULL;
}
由于某些原因,线程被创建,但在创建过程中,代码段出现了错误。我不确定它发生在哪里,但我非常确定它在threadcode函数中的某个地方,因为线程将开始创建,但随后将失败。传递给
pthread\u create()
的内容会犯严重错误:
无效*
。您正试图向其传递一个int
。这是实现定义的行为,在某些情况下可能会明智地工作,但最好避免它。给它传递一个实际的指针int
,那么至少应该在线程函数中将其转换回int
。实际上,您试图将其转换为一个字符*
,它甚至与您所传递的内容都不接近。然后尝试取消引用该伪指针以获取字符,这就是为什么要分段printf()
或fprintf()
之类的函数(或者perror()
,但对于一个简单的示例,无论如何它都会立即退出,我会抓住机会)。您没有显示实现,但是您正在调用的其他一些函数也有可能受到类似的保护
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t io_mtx = PTHREAD_MUTEX_INITIALIZER;
void * threadcode(void * arg)
{
const char c = *((char *) arg);
if ( pthread_mutex_lock(&io_mtx) != 0 ) {
perror("couldn't acquire mutex");
exit(EXIT_FAILURE);
}
printf("Entered thread for '%c'\n", c);
if ( pthread_mutex_unlock(&io_mtx) != 0 ) {
perror("couldn't release mutex");
exit(EXIT_FAILURE);
}
return NULL;
}
int main(void)
{
pthread_t tidn, tids, tide, tidw;
static char * dirs = "nsew";
/* Create threads */
if ( pthread_create(&tidn, NULL, threadcode, &dirs[0]) != 0 ) {
perror("couldn't create north thread");
return EXIT_FAILURE;
}
if ( pthread_create(&tids, NULL, threadcode, &dirs[1]) != 0 ) {
perror("couldn't create south thread");
return EXIT_FAILURE;
}
if ( pthread_create(&tide, NULL, threadcode, &dirs[2]) != 0 ) {
perror("couldn't create east thread");
return EXIT_FAILURE;
}
if ( pthread_create(&tidw, NULL, threadcode, &dirs[3]) != 0 ) {
perror("couldn't create west thread");
return EXIT_FAILURE;
}
/* State that threads are created */
if ( pthread_mutex_lock(&io_mtx) != 0 ) {
perror("couldn't acquire mutex");
exit(EXIT_FAILURE);
}
printf("Threads created\n");
if ( pthread_mutex_unlock(&io_mtx) != 0 ) {
perror("couldn't release mutex");
exit(EXIT_FAILURE);
}
/* Join threads */
if ( pthread_join(tidn, NULL) != 0 ) {
perror("couldn't join with north thread");
return EXIT_FAILURE;
}
if ( pthread_join(tids, NULL) != 0 ) {
perror("couldn't join with south thread");
return EXIT_FAILURE;
}
if ( pthread_join(tide, NULL) != 0 ) {
perror("couldn't join with east thread");
return EXIT_FAILURE;
}
if ( pthread_join(tidw, NULL) != 0 ) {
perror("couldn't join with west thread");
return EXIT_FAILURE;
}
return 0;
}
非常感谢。我想如果所有其他方法都失败了,我会传入一个char*,但我希望有一种方法可以简单地将字符传递到线程函数中,而不创建整个变量。
printf
、fprintf
和perror
都保证在POSIX中是安全的。@caf:谢谢,你说得对。线程安全并不总是需要的全部——例如,输出仍然可能在多个调用之间随机交错,因此可能仍然需要手动同步——但是在这个我们只关心单个调用的特定程序中,正如你所说的,这很好。我真的很好奇为什么这里需要pthread_mutex_lock和pthread_mutex_unlock这样的调用?@Subhajit:正如caf所提到的,在这种特殊情况下,它们不适用于POSIX系统,因为库实现了类似的保护级别。但是所有这些调用都操纵一个静态内部缓冲区,而这些内部机制的不变量可能在调用中间被短暂失效。如果一个线程在另一个线程调用一个标准IO函数的同时调用一个标准IO函数,那么这些内部机制很快就会被搞乱。
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t io_mtx = PTHREAD_MUTEX_INITIALIZER;
void * threadcode(void * arg)
{
const char c = *((char *) arg);
if ( pthread_mutex_lock(&io_mtx) != 0 ) {
perror("couldn't acquire mutex");
exit(EXIT_FAILURE);
}
printf("Entered thread for '%c'\n", c);
if ( pthread_mutex_unlock(&io_mtx) != 0 ) {
perror("couldn't release mutex");
exit(EXIT_FAILURE);
}
return NULL;
}
int main(void)
{
pthread_t tidn, tids, tide, tidw;
static char * dirs = "nsew";
/* Create threads */
if ( pthread_create(&tidn, NULL, threadcode, &dirs[0]) != 0 ) {
perror("couldn't create north thread");
return EXIT_FAILURE;
}
if ( pthread_create(&tids, NULL, threadcode, &dirs[1]) != 0 ) {
perror("couldn't create south thread");
return EXIT_FAILURE;
}
if ( pthread_create(&tide, NULL, threadcode, &dirs[2]) != 0 ) {
perror("couldn't create east thread");
return EXIT_FAILURE;
}
if ( pthread_create(&tidw, NULL, threadcode, &dirs[3]) != 0 ) {
perror("couldn't create west thread");
return EXIT_FAILURE;
}
/* State that threads are created */
if ( pthread_mutex_lock(&io_mtx) != 0 ) {
perror("couldn't acquire mutex");
exit(EXIT_FAILURE);
}
printf("Threads created\n");
if ( pthread_mutex_unlock(&io_mtx) != 0 ) {
perror("couldn't release mutex");
exit(EXIT_FAILURE);
}
/* Join threads */
if ( pthread_join(tidn, NULL) != 0 ) {
perror("couldn't join with north thread");
return EXIT_FAILURE;
}
if ( pthread_join(tids, NULL) != 0 ) {
perror("couldn't join with south thread");
return EXIT_FAILURE;
}
if ( pthread_join(tide, NULL) != 0 ) {
perror("couldn't join with east thread");
return EXIT_FAILURE;
}
if ( pthread_join(tidw, NULL) != 0 ) {
perror("couldn't join with west thread");
return EXIT_FAILURE;
}
return 0;
}
paul@horus:~/Documents/src/sandbox$ ./thread
Entered thread for 'n'
Entered thread for 's'
Entered thread for 'w'
Threads created
Entered thread for 'e'
paul@horus:~/Documents/src/sandbox$