1、点击菜单栏的“Project”选项卡,下拉列表的最后一项“Project options...”是对当前工程的的属性进行设置的。
2、选择弹出对话框中的“Compiler”选项卡。
3、将其中的“Runtime Library”的选择改为“Multithreaded (LIB)”。
4、将看到对话框最下面的文本框中发生了一些变化,新增了“-MT”选项,这与编译器一开始所报的错误提示给出的解决方案一致。
5、页面的设置完成后,再对该源码进行编译时,就能愉快地看到编译完全成功。
目录:Windows操作系统,C语言实现多线程
Windows下的多线程(不带停止)
Linux操作系统,C语言实现多线程: #include <stdio.h>#include <stdlib.h>
#include <pthread.h>
void * ThreadOne ( void * threadArg )
{
printf ( "线程开始啦,参数是:%s\n" , (char *)threadArg )
return NULL
}
int main ( void )
{
pthread_t ThreadID /* 记录线程标识符 */
void * waitingResult /* 等待线程退出的等待结果 */
int errorCode /* 记录线程的错误代码 */
char * aMessage = "这是线程的参数"
/* 创建并启动线程ThreadOne。若返回值非零,则线程创建失败 */
errorCode = pthread_create( &ThreadID, NULL, ThreadOne, aMessage )
if ( errorCode != 0 )
{
printf ("线程ThreadOne创建失败。错误代码:%d\n", errorCode )
return EXIT_FAILURE
}
/* 等待线程标识符为的ThreadID的线程结束 */
errorCode = pthread_join( ThreadID, &waitingResult )
if ( errorCode != 0 )
{
printf ( "等待线程退出等待失败。错误代码:%d\n" , errorCode )
return EXIT_FAILURE
}
printf( "线程的返回值是%p\n", waitingResult )
return EXIT_SUCCESS
} Windows操作系统,C语言实现多线程: #include <stdio.h>
#include <windows.h>
DWORD APIENTRY ThreadOne ( LPVOID threadArg )
{
printf ( "线程开始啦,参数是:%s\n" , (char *)threadArg )
return 0
}
int main ( void )
{
HANDLE hThread /* 记录线程句柄 */
DWORD ThreadID /* 记录线程ID号 */
DWORD waitingResult /* 等待线程退出的等待结果 */
DWORD threadExitCode /* 记录线程的返回值 */
char * aMessage = "这是线程的参数"
/* 创建并启动线程ThreadOne,返回值为线程句柄,赋值给hThread */
hThread = CreateThread ( NULL, 0L, ThreadOne, (LPVOID)aMessage, 0L, &ThreadID )
if ( hThread == NULL )
{
printf ("线程ThreadOne创建失败。错误代码:%lu\n", GetLastError() )
return EXIT_FAILURE
}
/* 等待线程句柄为的hThread线程结束 */
waitingResult = WaitForSingleObject ( hThread, INFINITE )
if ( waitingResult == WAIT_FAILED )
{
printf ( "等待线程退出等待失败。错误代码:%lu\n" , GetLastError() )
return EXIT_FAILURE
}
if ( GetExitCodeThread ( hThread , &threadExitCode ) )
printf ( "线程的返回值是%lu\n", threadExitCode )
else
printf ( "获取线程的返回值获取失败。错误代码:%lu\n" , GetLastError() )
return EXIT_SUCCESS
} Windows下的多线程:(不带停止) #include <stdio.h>
#include <windows.h>
DWORD WINAPI duoxianchen(LPVOID lpParam)
int main(int argc, char *argv[])
{
int num=0
CreateThread(NULL,NULL,duoxianchen,&num,NULL, NULL)
while(1)
{
num++
printf("主线程! %05d\n",nu***eep(40)
}
return 0
}
DWORD WINAPI duoxianchen(LPVOID lpParam)
{
int* a=lpParam
while(1)
{
++*a
printf("副线程! %05d 0x%p\n",*a,a)
Sleep(80)
}
return 0
}
线程之间的同步和互斥解决的问题是线程对共同资源进行访问。Posix有两种方式:信号量和互斥锁;信号量适用同时可用的资源为多个的情况;互斥锁适用于线程可用的资源只有一个的情况
1、互斥锁:互斥锁是用加锁的方式来控制对公共资源的原子操作(一旦开始进行就不会被打断的操作)
互斥锁只有上锁和解锁两种状态。互斥锁可以看作是特殊意义的全局变量,因为在同一时刻只有一个线程能够对互斥锁进行操作;只有上锁的进程才可以对公共资源进行访问,其他进程只能等到该进程解锁才可以对公共资源进行操作。
互斥锁操作函数:
pthread_mutex_init()//初始化
pthread_mutex_lock()//上锁参数:pthread_mutex_t *mutex
pthread_mutex_trylock()//判断上锁 参数:pthread_mutex_t *mutex
pthread_mutex_unlock()//解锁参数:pthread_mutex_t *mutex
pthread_mutex_release()//消除互斥锁 参数:pthread_mutex_t *mutex
互斥锁分为快速互斥锁、递归互斥锁、检错互斥锁;在 init 的时候确定
int pthread_mutex_t(pthread_mutex_t *mutex, const pthread_mutex_t mutexattr)
第一个参数:进行操作的锁
mutexattr:锁的类型,默认快速互斥锁(阻塞)123456789
2、信号量:信号量本质上是一个计数器,在操作系统做用于PV原子操作;
P操作使计数器-1;V操作使计数器+1.
在互斥操作中可以是使用一个信号量;在同步操作中需要使用多个信号量,并设置不同的初始值安排它们顺序执行
sem_init() // 初始化操作
sem_wait() // P操作,计数器减一;阻塞参数:sem_t *sem
sem_trywait() // P操作,计数器减一;非阻塞 参数:sem_t *sem
sem_post()// V操作,计数器加一 参数:sem_t *sem
sem_destroy() // 销毁信号量参数:sem_t *sem
sem_init(sem_t *sem, int pshared, int value)
pshared用于指定多少个进程共享;value初始值